在 SQL 中声明和使用用户定义的 Table 类型

Declaring and Consuming User Defined Table Types in SQL

我正在尝试在 SQL 中使用用户定义的 Table 类型,但遇到了我没有预料到的问题。相关部分代码如下:

declare @customer varchar(10), @prodgroup varchar(10)

SET @customer = 'CUST123'
SET @prodgroup = 'AA9A3'

declare @pctn  prices_ctn --User defined table type
declare @ppck  prices_pck --User defined table type
declare @psin  prices_sin --User defined table type

declare @sqlctn varchar(8000), @sqlpck varchar(8000), @sqlsin varchar(8000)
SET @sqlctn = 'insert into @pctn select product_code, price FROM pricing_table with (nolock) WHERE price_list  = ''CTN'' AND product_code like ''' + @prodgroup + ''''
SET @sqlpck = 'insert into @ppck select product_code, price FROM pricing_table with (nolock) WHERE price_list  = ''PCK'' AND product_code like ''' + @prodgroup + ''''
SET @sqlsin = 'insert into @psin select product_code, price FROM pricing_table with (nolock) WHERE price_list  = ''SIN'' AND product_code like ''' + @prodgroup + ''''

exec(@sqlctn)
exec(@sqlpck)
exec(@sqlsin)

但是,当我执行代码时,每个用户定义的 table 类型都出现 'Must declare the table variable' 错误。

Table 类型全部创建并显示在 SSMS 的 'User-Defined Table Types' 中。 SQL 版本为 12.0.2000.8.

我做错了什么?

table 变量不能在动态 SQL 查询中使用,因为它像任何其他变量一样仅存在于当前会话中。

EXEC 创建第二个会话,其中 none 个变量存在,除非您将它们作为参数传递。

在这些查询中,table 变量超出了动态 SQL 范围。

Table 类型和变量用于将 table 传递给存储过程(只读 table)或从过程或函数中获取 table。

有两种方法可以让它发挥作用:

  • 插入

    declare @params = N'@prodgroup varchar(10)';
    SET @sqlctn = 'select product_code, price FROM pricing_table with (nolock) WHERE price_list  = ''CTN'' AND product_code like @prodgroup; '
    
    declare @pctn  prices_ctn --User defined table type
    insert into @pctn  
    exec sp_executesql @sqlctn, @params, @prodgroup = @prodgroup;
    
  • 温度Table

    create table  #pctn  (...)
    declare @params = N'@prodgroup varchar(10)';
    SET @sqlctn = 'insert into #pctn select product_code, price FROM pricing_table with (nolock) WHERE price_list  = ''CTN'' AND product_code like @prodgroup '
    exec sp_executesql @sqlctn, @params, @prodgroup = @prodgroup;
    

请注意,我使用的是 sp_executesql 和一个参数变量。这是调用动态 SQL 的最佳方式。应避免单独执行和参数的字符串连接。