sql-server - 创建具有与另一个表完全相同的结构的表变量
问题描述
在 T-SQL 中,我可以使用如下语法创建表变量
DECLARE @table AS TABLE (id INT, col VARCHAR(20))
现在,如果我想在数据库中创建一个真实表的精确副本,我会做这样的事情
SELECT *
FROM INFOMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MY_TABLE_NAME'
检查列数据类型和最大长度,并开始创建@table
变量,将变量、数据类型和最大长度一一命名,这不是很有效。我可以知道是否有任何更简单的方法可以做到这一点
DECLARE @table AS TABLE = SOME_REAL_TABLE_IN_DATABASE
此外,有什么方法可以检索列的名称、数据类型和最大长度,并直接在声明中使用它,例如
DECLARE @table AS TABLE (@col1_specs)
先感谢您。
编辑:感谢您的回答和评论,我们可以这样做,@table_variable
但只能在动态 SQL 中这样做,这不利于可维护性。但是,我们可以使用#temp_table
.
根据 Ezlo 的回答,我们可以这样做:
SELECT TABLE.* INTO #TEMP_TABLE FROM TABLE
有关更多信息,请参阅此答案。
解决方案
对象名称和数据类型(表、列等)不能参数化(不能来自变量)。这意味着您不能执行以下操作(例如,复制表结构需要这样做):
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)
Msg 137, Level 15, State 2, Line 1
必须声明标量变量“@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
推荐阅读
- cuda - 错误:类“cooperative_groups::__v1::thread_block”没有成员“is_valid”
- ubuntu - 如何在 Ubuntu 14 中仅获取文件的 sha512sum?
- c# - 使用列表而不是数组的问题
- react-native - 如何在底部选项卡导航器中隐藏标签反应导航 v5
- javascript - 如果资产加载失败,则测试失败
- ios - 如何导入 cookieMaster(或任何已安装的外部节点包)?
- python - 将浮点列表列表转换为一个列表
- google-cloud-platform - MLflow 将工件存储在 GCP 存储桶上,但无法读取它们
- python - 如何在复杂的层次结构中进行子类化?
- angular - REST 适用于获取所有用户,但无法让一位用户说请求的资源上不存在“Access-Control-Allow-Origin”标头