SELECCIONAR * EXCEPTO
Edit: entendo a preocupação de todos com SELECT *
. Conheço os riscos associados a SELECT *
. No entanto, isto, pelo menos na minha situação, não seria usado para qualquer código de Nível de produção, ou mesmo código de Nível de desenvolvimento; estritamente para depuração, quando eu preciso ver todos os valores facilmente.
14 answers
declare @sql varchar(8000),
@table_id int,
@col_id int
set @sql = 'select '
select @table_id = id from sysobjects where name = 'MY_Table'
select @col_id = min(colid) from syscolumns where id = @table_id and name <> 'description'
while (@col_id is not null) begin
select @sql = @sql + name from syscolumns where id = @table_id and colid = @col_id
select @col_id = min(colid) from syscolumns where id = @table_id and colid > @col_id and name <> 'description'
if (@col_id is not null) set @sql = @sql + ','
print @sql
end
set @sql = @sql + ' from MY_table'
exec @sql
Crie uma vista na tabela que não inclua as colunas blob
O DB2 permite isto. As colunas têm um atributo / especificador de Hidden
.
Da documentação do syscolumns
Escondido
CHAR (1) NÃO NULO COM O VALOR POR OMISSÃO ' N '
Indica se a coluna está implicitamente escondida:Parcialmente escondido. A coluna está implicitamente escondida De SELECT *.
Não está escondido. A coluna é visível para todas as declarações SQL.
Criar a documentação da tabela como parte da criação na sua coluna, iria indicar o modificador IMPLICITLY HIDDEN
Um exemplo DDL de colunas implicitamente escondidas segue
CREATE TABLE T1
(C1 SMALLINT NOT NULL,
C2 CHAR(10) IMPLICITLY HIDDEN,
C3 TIMESTAMP)
IN DB.TS;
Se esta capacidade é tão importante para conduzir a adopção do DB2 é deixada como um exercício para futuros leitores.
Sim! A linguagem verdadeiramente relacional Tutorial D permite que a projeção seja expressa em termos dos atributos a serem removidos em vez dos que devem ser mantidos, por exemploExiste algum RDBMS que implemente algo como seleccionar * excepto
my_relvar { ALL BUT description }
De facto, o seu equivalente a SELECT *
SQL é { ALL BUT }
.
Também foi pedido explicitamente para o servidor SQL , mas o pedido foi fechado como 'não vai corrigir'.
Há algum RDBMS que implemente algo como seleccionar * excepto?
SIM, o Google Big Query implements selecciona * excepto:
Uma instrução SELECT * EXCEPT especifica os nomes de uma ou mais colunas para excluir do resultado. Todos os nomes das colunas correspondentes são omitidos do resultado.
WITH orders AS(
SELECT 5 as order_id,
"sprocket" as item_name,
200 as quantity
)
SELECT * EXCEPT (order_id)
FROM orders;
Resultado:
+-----------+----------+
| item_name | quantity |
+-----------+----------+
| sprocket | 200 |
+-----------+----------+
Afasta-te da selecção *, estás a preparar-te para problemas. indique sempre exactamente quais as colunas que deseja. É de fato bastante refrescante que o "recurso" que você está pedindo não existe.
Eu acredito que a lógica para que não exista é que o autor de uma consulta deve (para o bem do desempenho) apenas pedir o que eles vão olhar/precisar (e, portanto, saber que colunas especificar) -- se alguém adiciona mais algumas bolhas no futuro, você estaria puxando para trás campos potencialmente grandes que você não vai precisar.
Sim, finalmente há:) a norma SQL 2016 define funções de tabela polimórficas
O SQL: 2016 introduz funções de tabela polimórficas (PTF) que não precisam especificar o tipo de resultado antecipadamente. Em vez disso, eles podem fornecer um procedimento de componente de descrição que determina o tipo de retorno no tempo de execução. Nem o autor do PTF nem o usuário do PTF precisam declarar as colunas retornadas com antecedência.
Os PTFs descritos pelo SQL: 2016 não são ainda disponível em qualquer banco de dados testado.10 os leitores interessados podem referir-se ao relatório técnico gratuito "Polymorphic table functions in SQL" lançado pela ISO. A seguir, alguns dos exemplos discutidos no relatório:
CSVreader, que lê a linha de cabeçalho de um arquivo CVS para determinar o número e os nomes das colunas de retorno
Pivot (na verdade, unpivot), que transforma grupos de colunas em linhas (exemplo: fonetype, phonenumber) -- me: acabou-se cordas revestidas de ferro ou aço:)
TopNplus, que passa por N linhas por partição e uma linha extra com os totais das restantes linhas
Oracle 18c
implementa este mecanismo. 18c Skip_col Polymorphic Table Function Example Oracle Live SQL and Skip_col Polymorphic Table Function Example
Este exemplo mostra como ignorar os dados com base no nome / tipo específico de Dados:
CREATE PACKAGE skip_col_pkg AS
-- OVERLOAD 1: Skip by name
FUNCTION skip_col(tab TABLE, col columns)
RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg;
FUNCTION describe(tab IN OUT dbms_tf.table_t,
col dbms_tf.columns_t)
RETURN dbms_tf.describe_t;
-- OVERLOAD 2: Skip by type --
FUNCTION skip_col(tab TABLE,
type_name VARCHAR2,
flip VARCHAR2 DEFAULT 'False')
RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg;
FUNCTION describe(tab IN OUT dbms_tf.table_t,
type_name VARCHAR2,
flip VARCHAR2 DEFAULT 'False')
RETURN dbms_tf.describe_t;
END skip_col_pkg;
E corpo:
CREATE PACKAGE BODY skip_col_pkg AS
/* OVERLOAD 1: Skip by name
* NAME: skip_col_pkg.skip_col
* ALIAS: skip_col_by_name
*
* PARAMETERS:
* tab - The input table
* col - The name of the columns to drop from the output
*
* DESCRIPTION:
* This PTF removes all the input columns listed in col from the output
* of the PTF.
*/
FUNCTION describe(tab IN OUT dbms_tf.table_t,
col dbms_tf.columns_t)
RETURN dbms_tf.describe_t
AS
new_cols dbms_tf.columns_new_t;
col_id PLS_INTEGER := 1;
BEGIN
FOR i IN 1 .. tab.column.count() LOOP
FOR j IN 1 .. col.count() LOOP
tab.column(i).pass_through := tab.column(i).description.name != col(j);
EXIT WHEN NOT tab.column(i).pass_through;
END LOOP;
END LOOP;
RETURN NULL;
END;
/* OVERLOAD 2: Skip by type
* NAME: skip_col_pkg.skip_col
* ALIAS: skip_col_by_type
*
* PARAMETERS:
* tab - Input table
* type_name - A string representing the type of columns to skip
* flip - 'False' [default] => Match columns with given type_name
* otherwise => Ignore columns with given type_name
*
* DESCRIPTION:
* This PTF removes the given type of columns from the given table.
*/
FUNCTION describe(tab IN OUT dbms_tf.table_t,
type_name VARCHAR2,
flip VARCHAR2 DEFAULT 'False')
RETURN dbms_tf.describe_t
AS
typ CONSTANT VARCHAR2(1024) := upper(trim(type_name));
BEGIN
FOR i IN 1 .. tab.column.count() LOOP
tab.column(i).pass_through :=
CASE upper(substr(flip,1,1))
WHEN 'F' THEN dbms_tf.column_type_name(tab.column(i).description)
!=typ
ELSE dbms_tf.column_type_name(tab.column(i).description)
=typ
END /* case */;
END LOOP;
RETURN NULL;
END;
END skip_col_pkg;
E Utilização da amostra:
-- skip number cols
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number');
-- only number cols
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number', flip => 'True')
-- skip defined columns
SELECT *
FROM skip_col_pkg.skip_col(scott.emp, columns(comm, hiredate, mgr))
WHERE deptno = 20;
Eu recomendo ler o exemplo inteiro (criando funções autônomas em vez de chamadas de pacotes).
Poderá sobrecarregar facilmente o método de ignorar, por exemplo: ignorar as colunas que não começam/terminam com prefixo/sufixo específico.
Como outros dizem: Seleccionar * é uma má ideia.
Algumas razões:
- Obter apenas o que você precisa (qualquer coisa mais é um desperdício)
- indexação (indexar o que você precisa e você pode obtê-lo mais rapidamente. Se você pedir um monte de colunas não indexadas, também, seus planos de consulta vai sofrer.
declare @sql nvarchar(max)
@table char(10)
set @sql = 'select '
set @table = 'table_name'
SELECT @sql = @sql + '[' + COLUMN_NAME + '],'
FROM INFORMATION_SCHEMA.Columns
WHERE TABLE_NAME = @table
and COLUMN_NAME <> 'omitted_column_name'
SET @sql = substring(@sql,1,len(@sql)-1) + ' from ' + @table
EXEC (@sql);
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name FROM sys.columns WHERE name <> 'colName' AND object_id = (SELECT id FROM sysobjects WHERE name = 'tblName')
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + 'tblName'
EXEC sp_executesql @SQL
Procedimento Armazenado:
Usp_selectallexept 'tblname','colname'
ALTER PROCEDURE [dbo].[usp_SelectAllExcept]
(
@tblName SYSNAME
,@exception VARCHAR(500)
)
AS
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name from sys.columns where name <> @exception and object_id = (Select id from sysobjects where name = @tblName)
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @tblName
EXEC sp_executesql @SQL
A minha inspiração foi @Jasmine e @Zerubbabel answers. No meu caso, tenho esquemas diferentes, por isso o mesmo nome de tabela aparece mais de uma vez no sys.objecto. Como isso pode ajudar alguém com o mesmo cenário, aqui vai:
ALTER PROCEDURE [dbo].[_getLineExceptCol]
@table SYSNAME,
@schema SYSNAME,
@LineId int,
@exception VARCHAR(500)
AS
DECLARE @SQL NVARCHAR(MAX)
BEGIN
SET NOCOUNT ON;
SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name
FROM sys.columns
WHERE name <> @exception
AND object_id = (SELECT object_id FROM sys.objects
WHERE name LIKE @table
AND schema_id = (SELECT schema_id FROM sys.schemas WHERE name LIKE @schema))
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @schema + '.' + @table + ' WHERE Id = ' + CAST(@LineId AS nvarchar(50))
EXEC(@SQL)
END
GO
A opção da tabela Temp aqui, basta largar as colunas não necessárias e seleccionar * da tabela temp alterada.
/* Get the data into a temp table */
SELECT * INTO #TempTable
FROM
table
/* Drop the columns that are not needed */
ALTER TABLE #TempTable
DROP COLUMN [columnname]
SELECT * from #TempTable
Por uma questão de Completude, isto é possível no dialecto DremelSQL, fazendo algo como:
WITH orders AS
(SELECT 5 as order_id,
"foobar12" as item_name,
800 as quantity)
SELECT * EXCEPT (order_id)
FROM orders;
+-----------+----------+
| item_name | quantity |
+-----------+----------+
| foobar12 | 800 |
+-----------+----------+
Também parece haver outra maneira de o fazer Aqui sem Dremel.