在T-SQL中,我可以使用
这样的语法创建表变量DECLARE @table AS TABLE (id INT, col VARCHAR(20))
就目前而言,如果要在数据库中创建真实表的精确副本,请执行以下操作
SELECT *
FROM INFOMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MY_TABLE_NAME'
检查列的数据类型以及最大长度,并开始创建@table
变量,将变量,数据类型和max_length逐一命名,这不是很有效。我是否可以知道
DECLARE @table AS TABLE = SOME_REAL_TABLE_IN_DATABASE
此外,有什么方法可以检索列名,数据类型和列的最大长度,并直接在声明中使用它,例如
DECLARE @table AS TABLE (@col1_specs)
谢谢。
答案 0 :(得分:2)
对象名称和数据类型(表,列等)无法参数化(不能来自变量)。这意味着您不能执行以下操作(例如,复制表结构将需要执行以下操作):
DECLARE @TableName VARCHAR(50) = 'Employees'
SELECT
T.*
FROM
@TableName AS T
唯一的解决方法是使用动态SQL:
DECLARE @TableName VARCHAR(50) = 'Employees'
DECLARE @DynamicSQL VARCHAR(MAX) = '
SELECT
T.*
FROM
' + QUOTENAME(@TableName) + ' AS T '
EXEC (@DynamicSQL)
但是,在动态SQL外部声明的变量(标量和表变量)将失去作用域,因为它们将失去作用域:
DECLARE @VariableOutside INT = 10
DECLARE @DynamicSQL VARCHAR(MAX) = 'SELECT @VariableOutside AS ValueOfVariable'
EXEC (@DynamicSQL)
第1级第15行第2行137消息
必须声明标量变量“ @VariableOutside”。
这意味着您将必须在动态SQL中声明变量:
DECLARE @DynamicSQL VARCHAR(MAX) = 'DECLARE @VariableOutside INT = 10
SELECT @VariableOutside AS ValueOfVariable'
EXEC (@DynamicSQL)
结果:
ValueOfVariable
10
这带来了我的结论:如果要动态创建现有表的副本作为表变量,则对表变量的所有访问都必须在动态SQL脚本内,这是一个很大的麻烦,并且有一些缺点(难以维护和阅读,更容易出错等)。
一种常见的方法是改为使用临时表。进行SELECT * INTO
创建它们将继承表的数据类型。如果您不希望插入实际的行,则可以添加始终为假的WHERE
条件(例如WHERE 1 = 0
)。
IF OBJECT_ID('tempdb..#Copy') IS NOT NULL
DROP TABLE #Copy
SELECT
T.*
INTO
#Copy
FROM
YourTable AS T
WHERE
1 = 0
答案 1 :(得分:1)
两个问题的答案都是简单的否。
尽管,我同意您的看法,T-SQL应该以这种方式进行更改。
在第一种情况下,它意味着具有克隆表结构的命令。
当然,可以使用SQLCLR进行自己的T-SQL扩展。