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)
我知道这被标记为 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 没有什么比这更容易的了。
归档时间: |
|
查看次数: |
10466 次 |
最近记录: |