使用条件动态创建临时表

Bij*_*ose 6 sql-server t-sql sql-server-2008-r2

我正在尝试使用以下代码动态创建一个临时表,并且我知道我们不能为同一个表创建两个创建语句。是否有解决方法可以像下面的代码一样以有条件的方式放置它。

CREATE PROC test @var1 CHAR(1)
as
BEGIN
IF(@var1 = X)
BEGIN 
SELECT * INTO #result
FROM TABLE1
END
IF(@var1 = Y)
BEGIN 
SELECT * INTO #result
FROM TABLE2
END
IF(@var1 = Z)
BEGIN 
SELECT * INTO #result
FROM TABLE3
END

SELECT * FROM #result r
END
Run Code Online (Sandbox Code Playgroud)

目标是最终有一个名为 #result 的表,其中包含基于变量 (@var1) 值的列

编辑 1: 因为这是使用动态 SQL 的一个很好的候选者,如下所示,但我将无法使用#result动态 SQL 范围之外的表,而这正是我需要的。

CREATE PROC test @var1 CHAR(1)
as
BEGIN
-- USING  dynamic sql
DECLARE @sql VARCHAR(MAX)
IF(@var1 = 'X')
BEGIN 
SET @sql ='SELECT t.[name],t.[object_id],t.[principal_id] INTO #result
FROM sys.tables t'
END
IF(@var1 = 'Y')
BEGIN 
SET @sql ='SELECT t.[name],t.[object_id],t.[principal_id],t.[schema_id] INTO #result
FROM sys.tables t'
END
IF(@var1 = 'Z')
BEGIN 
SET @sql ='SELECT t.[name],t.[object_id],t.[principal_id],t.[schema_id],t.[parent_object_id] INTO #result
FROM sys.tables t'
END

EXEC (@sql)
SELECT * FROM #result r
END
Run Code Online (Sandbox Code Playgroud)

Eri*_*ing 7

支持的?

我知道这被标记为 2008R2。由于已正式停止支持,因此您将来可能会进行升级。如果您最终使用的 SQL Server 版本大于 2012,则可以使用如下代码:

CREATE OR ALTER PROCEDURE dbo.dynamic_temp ( @TableName NVARCHAR(128))
AS
BEGIN
    SET NOCOUNT ON;

    CREATE TABLE #t ( Id INT );
    DECLARE @sql NVARCHAR(MAX) = N'';

    IF @TableName = N'Users'
        BEGIN
            SET @sql = @sql + N'SELECT TOP 10 * FROM dbo.Users AS u WHERE u.Reputation > @i';
        END;

    IF @TableName = N'Posts'
        BEGIN
            SET @sql = @sql + N'SELECT TOP 10 * FROM dbo.Posts AS p WHERE p.Score > @i';
        END;

    SELECT   column_ordinal, name, system_type_name
    INTO     #dfr
    FROM     sys.dm_exec_describe_first_result_set(@sql, NULL, 0)
    ORDER BY column_ordinal;

    DECLARE @alter NVARCHAR(MAX) = N'ALTER TABLE #t ADD ';

    SET @alter += STUFF((   SELECT   NCHAR(10) + d.name + N' ' + d.system_type_name + N','
                            FROM     #dfr AS d
                            WHERE    d.name <> N'Id'
                            ORDER BY d.column_ordinal
                            FOR XML PATH(N''), TYPE ).value(N'.[1]', N'NVARCHAR(4000)'), 1, 1, N'');

    SET @alter = LEFT(@alter, LEN(@alter) - 1);

    EXEC ( @alter );

    INSERT #t
    EXEC sys.sp_executesql @sql, N'@i INT', @i = 10000;

    SELECT *
    FROM   #t;

END;
GO
Run Code Online (Sandbox Code Playgroud)

这个想法是使用dm_exec_describe_first_result_set来确定您的结果生成哪些列,以及它们的数据类型。我们可以使用它来生成动态 ALTER TABLE 语句,将这些列添加到在动态 SQL 范围之外创建的基本 #temp 表中。

这使得从中插入和选择数据变得非常容易。

当我想起这个问题时,我正在写博客。再次,抱歉,< 2012 没有什么比这更容易的了。


小智 0

@biju,如何将整个代码放入动态sql中并同时放入选择。那么就不会有任何表范围的问题。