【问题标题】:Script to create dynamic tables创建动态表的脚本
【发布时间】:2015-01-31 20:46:56
【问题描述】:

我正在尝试创建一个动态脚本来创建多个表。下面是一个示例

--exec USP_Dynamic_tablescript
Create procedure USP_Dynamic_tablescript
as 
    DECLARE @SQLStmt nvarchar(3000)
    DECLARE @table_name nvarchar(3000)
    DECLARE @i int

    set @i=1

    while(@i<=3)
    begin
        set @table_name = '#tblSales' + convert(varchar(10),@i)

        SET @SQLStmt = 'create  TABLE ' + @table_name +  '( ' + ' CityId int , ' +
                       ' SalesPersonId int , ' + ' SalesAmount numeric(10,2), ' +
                       ' MetTarget nvarchar(2) ' + ' ) '+
                       ' ON [PRIMARY] WITH (DATA_COMPRESSION = NONE)'

        print @table_name

        EXEC sp_executesql @SQLStmt

        set @i = @i + 1
    end

    SELECT * from #tblSales1

    INSERT INTO #tblSales1(CityId, SalesPersonId, SalesAmount, MetTarget) 
    VALUES (1, 101, 1650.00, 'Y')

我需要对这些临时表运行 DML 语句。

如果我尝试,我会遇到错误。请帮助我了解范围,表已成功创建,但我如何对其运行 DML 操作。

消息 208,级别 16,状态 0,过程 USP_Dynamic_tablescript,第 31 行
对象名称“#tblSales1”无效。

【问题讨论】:

  • 您正在 Dynamic 查询 中创建一个 Temp 表,该表只能在 Dynamic Query 会话中访问无法在 Dynamic Query 之外访问它
  • 如果您想撤回您的问题,请将其删除,但不要编辑文本,以便现有答案与您的问题无关。

标签: sql sql-server tsql stored-procedures temp-tables


【解决方案1】:

正如我在 cmets 中提到的,您无法访问 动态查询范围之外的临时表,该临时表是在动态查询中创建。

另一种方法是创建可在 Dynamic Query 之外使用的 Global TempTable 或 Physical table

DECLARE @SQLStmt nvarchar(3000)
DECLARE @table_name nvarchar(3000)
DECLARE @i int

set @i=1

while(@i<=3)
begin
    set @table_name = '##tblSales' + convert(varchar(10),@i)

    SET @SQLStmt = 'create  TABLE ' + @table_name +  '( ' + ' CityId int , ' +
                   ' SalesPersonId int , ' + ' SalesAmount numeric(10,2), ' +
                   ' MetTarget nvarchar(2) ' + ' ) '+
                   ' ON [PRIMARY] WITH (DATA_COMPRESSION = NONE)'

    print @table_name

    EXEC sp_executesql @SQLStmt

    set @i = @i + 1
end

SELECT * from ##tblSales1

【讨论】:

  • 嗨,这会起作用,但如果我们要使用全局临时表,那么其他用户可以访问该表,我会避免使用它。有没有其他的方式或不同的逻辑?
  • @Thomas_ITsavvy 是的,在这种情况下它会失败。为什么要动态创建表?尝试改变这种方法
  • @NoDisplayName。根据要求,没有。在我收到的城市中,我需要创建那么多表并存储信息,然后链接到其他表,这是一个很大的 sp。如果我采用您的方法,请建议,如果我删除 SP 的全局临时表端会怎样,它会影响其他用户吗?
  • @Thomas_ITsavvy 本地临时表仅在与 SQL Server 实例首次创建或引用表时的同一连接期间对其创建者可见。用户断开与 SQL Server 实例的连接后,本地临时表将被删除。全局临时表在创建后对任何用户和任何连接都是可见的,并在引用该表的所有用户与 SQL Server 实例断开连接时被删除。因此,您可以随时删除全局临时表,而无需
【解决方案2】:
    CREATE PROCEDURE USP_Dynamic_tablescript
AS
DECLARE @SQLStmt NVARCHAR(3000)
    ,@table_name NVARCHAR(3000)
    ,@i INT

SET @i = 1

WHILE (@i <= 3)
BEGIN
    SET @table_name = '##tblSales' + convert(VARCHAR(10), @i)
    SET @SQLStmt = 'IF OBJECT_ID(''Tempdb..' + @table_name + ''') IS NOT NULL' + CHAR(10) + 
                    'DROP TABLE ' + @table_name + CHAR(10) + 
                    'CREATE  TABLE ' + @table_name + CHAR(10) + 
                    '(CityId int ,' + CHAR(10) + 
                    ' SalesPersonId int ,' + CHAR(10) + 
                    ' SalesAmount numeric(10,2),' + CHAR(10) + 
                    ' MetTarget nvarchar(2) )' + CHAR(10) + 
                    ' ON [PRIMARY] WITH (DATA_COMPRESSION = NONE)'

    PRINT @SQLStmt

    EXEC sp_executesql @SQLStmt

    SET @i = @i + 1
END

INSERT INTO ##tblSales1 (
    CityId
    ,SalesPersonId
    ,SalesAmount
    ,MetTarget
    )
VALUES (
    1
    ,101
    ,1650.00
    ,'Y'
    )

SELECT *
FROM ##tblSales1

【讨论】:

  • 当临时表被另一个用户在另一个会话中使用时,这将删除临时表,这不应该发生
  • @NoDisplayName 是的,我同意你的观点,因为它是全局临时的,但是我在阅读你的代码和它下面的 cmets 之前编写了这段代码,我认为问题只是在使用过程中的临时表
猜你喜欢
  • 1970-01-01
  • 2013-09-10
  • 2023-03-09
  • 1970-01-01
  • 2011-11-24
  • 2019-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多