我需要将查询存储为SQL Server中的存储过程。
我还需要传递定义表名和列名的参数。
这是我想要的查询,我试图将它存储在一个字符串中然后EXECUTE
但是没有成功,我可以解决这个问题吗?
CREATE PROCEDURE sp_selectAllParents @id int, @tableid varchar(30), @tablename varchar(30)
AS BEGIN
SET NOCOUNT ON;
WITH ct AS (
SELECT * FROM @tablename t WHERE @tableid = @id
UNION ALL
SELECT t.* FROM @tablename t JOIN ct ON t.parentId = ct.@tableid
)
SELECT * FROM @tablename t WHERE @tableid NOT IN (SELECT @tableid FROM ct)
END
编辑: 我的尝试是:
DECLARE @sql varchar(255)
SET @sql = 'WITH ct AS (SELECT * FROM @tablename t WHERE @tableid = @id UNION ALL SELECT t.* FROM @tablename t JOIN ct ON t.parentId = ct.@tableid) SELECT * FROM @tablename t WHERE @tableid NOT IN (SELECT @tableid FROM ct)'
EXEC(@sql)
答案 0 :(得分:3)
正如我已经在评论部分中所做的那样,这是一个坏主意。你应该重新考虑你的解决方案。
存储过程必须如下所示:
CREATE PROCEDURE selectAllParents @id int, @tableid sysname, @tablename sysname
AS
BEGIN
SET NOCOUNT ON;
-- Guards against SQL Injection attacks (replace ' with '')
SET @tableid=REPLACE(@tableid,'''','''''');
SET @tablename=REPLACE(@tablename,'''','''''');
DECLARE @stmt NVARCHAR(4000);
SET @stmt=
';WITH ct AS ('+
'SELECT * FROM ' + QUOTENAME(@tablename) + ' t WHERE ' + QUOTENAME(@tableid) + '= @id ' +
'UNION ALL ' +
'SELECT t.* FROM ' + QUOTENAME(@tablename) + ' t JOIN ct ON t.parentId = ct.' + QUOTENAME(@tableid) +
')'+
'SELECT * FROM ' + QUOTENAME(@tablename) +' t WHERE ' + QUOTENAME(@tableid) + ' NOT IN (SELECT ' + QUOTENAME(@tableid) +' FROM ct);';
EXEC sp_executesql
@stmt,
N'@id int',
@id;
END
GO
答案 1 :(得分:1)
如果您要将表名作为参数发送,则需要创建动态查询字符串。可以帮助下面的脚本
CREATE PROCEDURE sp_selectAllParents @id int, @tableid varchar(30), @tablename varchar(30)
AS BEGIN
SET NOCOUNT ON;
SET @query=N'WITH ct AS (
SELECT * FROM @tablename t WHERE @tableid = @id
UNION ALL
SELECT t.* FROM @tablename t JOIN ct ON t.parentId = ct.@tableid
)
SELECT * FROM @tablename t WHERE @tableid NOT IN (SELECT @tableid FROM ct)'
EXECUTE sp_executesql @query, @id,@tablename,@tableid
END