创建具有与另一个表完全相同的结构的表变量

时间:2019-05-30 08:19:42

标签: sql-server tsql

在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)

谢谢。

2 个答案:

答案 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扩展。