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

时间:2015-11-09 10:06:02

标签: sql sql-server user-defined-types

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

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)

然而,当我执行代码时,我得到'必须声明表变量'每个用户定义的表类型的错误。

表格类型全部创建并显示在“用户定义的表格类型”中。在SSMS中。 SQL版本是12.0.2000.8。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

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

EXEC创建第二个会话,除非您将它们作为参数传递,否则不存在任何变量。

在这些查询中,表变量不在动态SQL范围内。

表类型和变量用于将表传递给存储过程(READ ONLY表)或从过程或函数中获取表。

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

  • 插入

    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;
    
  • 临时表

    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的最佳方法。应该避免单独的EXEC和参数的字符串连接。