我有一个现有的存储过程,它将源表名称和目标表名称作为 Varchar 参数,并执行一些复杂的逻辑。我的要求是使用源表的column1 并使用该值构建串联输出。例如,
表A
Column1
--------
090912
899823
687678
我仅采用前 2 位数字并将其连接起来以创建类似“09,89,68”的输出。这用于其他计算。
@AllCode
作为一个 varchar(max)
变量,我添加了下面的 select 语句,如果直接给出表名,它可以正常工作。现在,我尝试用 varchar 的输入参数替换 TableA。如果我使用变量,那么我应该使用 Exec 语句。这就是我努力包含 @allCode 变量赋值的地方。
is 行与实际表名称配合良好:
select @AllCode = @AllCode + ' ' + Code
from
(select distinct left(Column1,2) as Code
from TableA
where TableA.Processedflag is null) tmp
print @AllCode --> 09,89,68
我写了下面的代码。从上面的行分配子查询并将其添加到
@SqlQuery
变量。我不知道如何扩展此查询并使用 Exec 包含 @AllCode
变量赋值。
alter procedure temp.spSample
@SrcTbl varchar(100),
@TgtTbl varchar(100)
as
begin
declare @AllCode varchar(500);
declare @SqlQuery varchar(max);
set @SqlQuery = 'select distinct left(Column1,2) as Code from ' + @SrcTbl + ' where ' + @SrcTbl +'.ProcessedFlag is null';
exec(@SqlQuery);
end
如何在没有表变量的情况下实现上述功能?我无法使用表变量,因为它需要在存储过程之外创建。
我尝试使用表变量并将值存储在表变量中。但是,在同一个存储过程中,我无法使用 CREATE 表变量并在同一过程中使用表变量。我遇到了找不到表的问题。如果表是在外部创建的,它会工作得很好,但由于维护问题,我不想在外部创建它。
有什么建议吗,如何获得如上例中所述的串联值
@allCode
?没有表变量可以完成吗?
你的问题并不完全清楚,我很确定整个问题有更好的方法,但你可以尝试这个:
一般提示:
CONCAT
,然后使用+
。这对于各种类型和 NULL 效果更好。SELECT @var = @var + ...
进行字符串聚合。有一些奇怪的副作用。QUOTENAME()
。这有助于防止 SQL 注入。--创建测试场景
DROP TABLE IF EXISTS dummyTbl;
GO
CREATE TABLE dummyTbl(TheColumn VARCHAR(10), ProcessedFlag BIT);
GO
INSERT INTO dummyTbl VALUES ('090912',1)
,('899823',0)
,('123456',1)
,('654321',0)
,('687678',0);
GO
--这是聚合字符串值的最佳方式
DECLARE @allCodes VARCHAR(MAX)=
(
SELECT STRING_AGG(LEFT(t.TheColumn,2),',')
FROM dummyTbl t
WHERE t.ProcessedFlag=0
);
PRINT @allCodes;
GO
--在两者之间使用 JSON 来允许变量列名称(但不适用于表名称)的技巧
DECLARE @columnName VARCHAR(100)='TheColumn';
DECLARE @allCodes VARCHAR(MAX)=
(
SELECT STRING_AGG(LEFT(TheValue.OfColumn,2),',')
FROM dummyTbl t
CROSS APPLY(SELECT JSON_VALUE((SELECT t.* FOR JSON PATH, WITHOUT_ARRAY_WRAPPER),CONCAT('$.',@columnName))) TheValue(OfColumn)
WHERE t.ProcessedFlag=0
);
PRINT @allCodes;
GO
--从变量表和列中检索值的完全动态方法
--重要提示:在系统名周围使用
QUOTENAME()
。这有助于避免 SQL 注入。
DECLARE @tableName VARCHAR(100)='dummyTbl';
DECLARE @columnName VARCHAR(100)='TheColumn';
DECLARE @allCodes VARCHAR(MAX);
DECLARE @cmd NVARCHAR(MAX)=CONCAT
(
N'SELECT @allCodes=STRING_AGG(LEFT(t.',QUOTENAME(@columnName),',2),'','')
FROM ',QUOTENAME(@tableName),' t
WHERE t.ProcessedFlag=0;'
);
--This will execute the dynamic statement and *output* the assigned variable
EXEC sp_executesql @cmd, N'@allCodes VARCHAR(MAX) OUT', @allCodes OUTPUT;
PRINT @allCodes;
GO
--清洁
DROP TABLE IF EXISTS dummyTbl;
GO
结果,您将看到三倍相同的打印值链。