sql - 如何执行引用表变量的 SQL 字符串?

标签 sql sql-server

我在 SQL Server 2008 中有一个表变量

    DECLARE @specsAndModel TABLE
    (
        specName VARCHAR(50)
        ,specVal VARCHAR(50)
    )
    INSERT INTO @specsAndModel
    VALUES('[modelNumber]', 'F00-B4R')

然后,我稍后构建一个名为 @query 的字符串,最终尝试将其传递给 EXECUTE,如以下示例所示:

    DECLARE @query NVARCHAR(MAX);
    SET @query = 'SELECT specName, specVal FROM @specsAndModel'
    EXECUTE(@query)

但是,SQL Server 给我错误消息:必须声明表变量“@specsAndModel”。

经过一番搜索,我认为这可能与 execution context 有关。 ,但我一直没能解决这个问题。

我是否可以在调用执行函数时使用表变量?

最佳答案

您正在创建的表是一个表变量,在其初始范围之外不可用。有几种方法可以解决这个问题:

创建全局临时表(免责声明:如果多个用户尝试同时运行此表,这可能会导致问题。):

create table  ##specsAndModel 
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO ##specsAndModel
VALUES('[modelNumber]', 'F00-B4R')

DECLARE @query NVARCHAR(MAX);
SET @query = 'SELECT specName, specVal FROM ##specsAndModel'
EXECUTE(@query)

创建本地临时表而不是全局临时表:

create table  #specsAndModel 
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO #specsAndModel
VALUES('[modelNumber]', 'F00-B4R')

DECLARE @query NVARCHAR(MAX);
SET @query = 'SELECT specName, specVal FROM #specsAndModel'
EXECUTE(@query)

在动态 SQL 中执行创建表(丑陋):

DECLARE @query NVARCHAR(MAX);
SET @query = 'DECLARE @specsAndModel TABLE
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO @specsAndModel
VALUES(''[modelNumber]'', ''F00-B4R'')
SELECT specName, specVal FROM @specsAndModel'
exec(@query)

不要使用临时表,而是创建一个实际的表,然后在完成后将其删除(免责声明:如果多个用户尝试同时运行该表,这可能会导致问题。):

create TABLE specsAndModel 
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO specsAndModel
VALUES('[modelNumber]', 'F00-B4R')

DECLARE @query NVARCHAR(MAX);
SET @query = 'SELECT specName, specVal FROM specsAndModel'
EXECUTE(@query)  

drop table specsAndModel

这里是有关临时表和表变量的讨论的链接:

Should I use a #temp table or a @table variable?

编辑:您可以使用sp_executesql传入表变量:

create type specsAndModel as table (
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
 )
go
declare @t specsAndModel
insert @t VALUES('[modelNumber]', 'F00-B4R')

exec sp_executesql N'select specName, specVal from @var', N'@var specsAndModel readonly', @t

使用全局 ##temp 表和永久表都会存在运行风险,因为如果多个用户尝试运行该进程,则可能会发生冲突。

使用本地 #temp 表或使用 sp_executesql 传递表变量会更安全。

关于sql - 如何执行引用表变量的 SQL 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12059327/

相关文章:

sql - 如何在没有重复的情况下进行多个并发批量插入?

mysql - 如何使用 like 进行良好的 sql 搜索

sql-server - 如何获取所有数据库用户的列表

sql - SQL UPDATE 操作是否将数据读取到 "local memory"?

sql - 如何循环遍历sql中表的项目列表

sql - 更改 SQL Server 函数以接受新的可选参数

mysql - 将 csv 导入 mysql workbench 时的列名要求

PHP 发布 SQL 命令只会创建和删除表

SQL Server : use CASE with LIKE

sql-server - 比较 IDENTITY 列的 INT 与 BIGINT 时出现意外的性能结果