是否有任何RDBMS实现类似的东西SELECT * EXCEPT?我所追求的是获取除特定TEXT/BLOB字段之外的所有字段,我只想选择其他所有字段.
几乎每天我都会向我的同事抱怨有人应该实现这个......它非常烦人,它不存在.
编辑:我理解大家的关注SELECT *.我知道与之相关的风险SELECT *.但是,至少在我的情况下,这不会用于任何生产级代码,甚至是开发级代码; 严格用于调试,当我需要轻松查看所有值时.
正如我在一些评论中所说,我工作的地方严格来说是一个命令行商店,在ssh上做一切.这使得很难使用任何gui工具(不允许与数据库的外部连接)等.
谢谢你的建议.
Jas*_*ine 36
正如其他人所说,在查询中执行此操作并不是一个好主意,因为当有人在将来更改表结构时,它很容易出现问题.但是,有一种方法可以做到这一点......我无法相信我实际上在暗示这一点,但本着回答实际问题的精神......
使用动态SQL执行此操作...这将执行除"description"列之外的所有列.您可以轻松将其转换为函数或存储过程.
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
Run Code Online (Sandbox Code Playgroud)
Pau*_*xon 24
在表上创建一个不包含blob列的视图
DB2允许这样做.列的属性/说明符为Hidden.
HIDDEN
CHAR(1)NOT NULL WITH DEFAULT'N'
表示是否隐式隐藏了列:P部分隐藏.SELECT*隐式隐藏该列.
N没有隐藏.该列对所有SQL语句都可见.
创建表文档作为创建列的一部分,您可以指定IMPLICITLY HIDDEN修饰符
来自示例DDL 隐式隐藏的列如下
CREATE TABLE T1
(C1 SMALLINT NOT NULL,
C2 CHAR(10) IMPLICITLY HIDDEN,
C3 TIMESTAMP)
IN DB.TS;
Run Code Online (Sandbox Code Playgroud)
这种能力是否是推动DB2采用的交易制定者,这仍然是未来读者的一种练习.
是否有任何RDBMS实现SELECT*EXCEPT之类的东西?
是的,Google Big Query实现SELECT*EXCEPT:
SELECT*EXCEPT语句指定要从结果中排除的一个或多个列的名称.输出中省略了所有匹配的列名称.
WITH orders AS(
SELECT 5 as order_id,
"sprocket" as item_name,
200 as quantity
)
SELECT * EXCEPT (order_id)
FROM orders;
Run Code Online (Sandbox Code Playgroud)
输出:
+-----------+----------+
| item_name | quantity |
+-----------+----------+
| sprocket | 200 |
+-----------+----------+
Run Code Online (Sandbox Code Playgroud)
是否有任何RDBMS实现SELECT*EXCEPT之类的东西
是! 真正的关系语言教程D允许以要删除的属性而不是要保留的属性来表示投影
my_relvar { ALL BUT description }
Run Code Online (Sandbox Code Playgroud)
事实上,它相当于SQL的SELECT *是{ ALL BUT }.
您对SQL的建议是值得的,但我听说它已被用户组提交给SQL标准委员会并被供应商组拒绝:(
它也已明确请求SQL Server,但请求已关闭,因为"将无法修复".
是的,终于有了:) SQL 标准 2016 定义了多态表函数
\n\n\nSQL:2016 引入了不需要预先指定结果类型的多态表函数 (PTF)。相反,他们可以提供一个描述组件过程来确定运行时的返回类型。PTF的作者和PTF的用户都不需要提前声明返回的列。
\nSQL:2016 描述的 PTF 在任何经过测试的数据库中尚不可用。10 有兴趣的读者可以参考 ISO 发布的免费技术报告 \xe2\x80\x9cSQL\xe2\x80\x9d 中的多态表函数。以下是报告中讨论的一些示例:
\n\n
\n- \n
CSVreader,读取 CVS 文件的标题行以确定返回列的数量和名称
\n- \n
透视(实际上是逆透视),它将列组转换为行(例如:电话类型、电话号码)——我:不再有编码字符串:)
\n- \n
TopNplus,每个分区传递 N 行,并额外添加一行以及剩余行的总和
\n
Oracle 18c实施这一机制。18c Skip_col 多态表函数示例 Oracle Live SQL和Skip_col 多态表函数示例
此示例显示如何根据名称/特定数据类型跳过数据:
\nCREATE PACKAGE skip_col_pkg AS \n -- OVERLOAD 1: Skip by name \n FUNCTION skip_col(tab TABLE, col columns) \n RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg; \n \n FUNCTION describe(tab IN OUT dbms_tf.table_t, \n col dbms_tf.columns_t) \n RETURN dbms_tf.describe_t; \n \n -- OVERLOAD 2: Skip by type -- \n FUNCTION skip_col(tab TABLE, \n type_name VARCHAR2, \n flip VARCHAR2 DEFAULT \'False\') \n RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg; \n \n FUNCTION describe(tab IN OUT dbms_tf.table_t, \n type_name VARCHAR2, \n flip VARCHAR2 DEFAULT \'False\') \n RETURN dbms_tf.describe_t; \nEND skip_col_pkg;\nRun Code Online (Sandbox Code Playgroud)\n与身体:
\nCREATE PACKAGE BODY skip_col_pkg AS \n \n/* OVERLOAD 1: Skip by name \n * NAME: skip_col_pkg.skip_col \n * ALIAS: skip_col_by_name \n * \n * PARAMETERS: \n * tab - The input table \n * col - The name of the columns to drop from the output \n * \n * DESCRIPTION: \n * This PTF removes all the input columns listed in col from the output \n * of the PTF. \n*/ \n FUNCTION describe(tab IN OUT dbms_tf.table_t, \n col dbms_tf.columns_t) \n RETURN dbms_tf.describe_t \n AS \n new_cols dbms_tf.columns_new_t; \n col_id PLS_INTEGER := 1; \n BEGIN \n FOR i IN 1 .. tab.column.count() LOOP \n FOR j IN 1 .. col.count() LOOP \n tab.column(i).pass_through := tab.column(i).description.name != col(j); \n EXIT WHEN NOT tab.column(i).pass_through; \n END LOOP; \n END LOOP; \n \n RETURN NULL; \n END; \n \n /* OVERLOAD 2: Skip by type \n * NAME: skip_col_pkg.skip_col \n * ALIAS: skip_col_by_type \n * \n * PARAMETERS: \n * tab - Input table \n * type_name - A string representing the type of columns to skip \n * flip - \'False\' [default] => Match columns with given type_name \n * otherwise => Ignore columns with given type_name \n * \n * DESCRIPTION: \n * This PTF removes the given type of columns from the given table. \n*/ \n \n FUNCTION describe(tab IN OUT dbms_tf.table_t, \n type_name VARCHAR2, \n flip VARCHAR2 DEFAULT \'False\') \n RETURN dbms_tf.describe_t \n AS \n typ CONSTANT VARCHAR2(1024) := upper(trim(type_name)); \n BEGIN \n FOR i IN 1 .. tab.column.count() LOOP \n tab.column(i).pass_through := \n CASE upper(substr(flip,1,1)) \n WHEN \'F\' THEN dbms_tf.column_type_name(tab.column(i).description)\n !=typ \n ELSE dbms_tf.column_type_name(tab.column(i).description) \n =typ \n END /* case */; \n END LOOP; \n \n RETURN NULL; \n END; \n \nEND skip_col_pkg; \nRun Code Online (Sandbox Code Playgroud)\n以及示例用法:
\n-- skip number cols\nSELECT * FROM skip_col_pkg.skip_col(scott.dept, \'number\'); \n\n-- only number cols\nSELECT * FROM skip_col_pkg.skip_col(scott.dept, \'number\', flip => \'True\') \n\n-- skip defined columns\nSELECT * \nFROM skip_col_pkg.skip_col(scott.emp, columns(comm, hiredate, mgr)) \nWHERE deptno = 20;\nRun Code Online (Sandbox Code Playgroud)\n我强烈建议阅读整个示例(创建独立函数而不是包调用)。
\n您可以轻松地重载跳过方法,例如:跳过不以特定前缀/后缀开头/结尾的列。
\n\n相关:如何动态更改 SQL 查询中的列作者:Chris Saxon
\n