tsql 动态 table 存储过程
tsql dynamic table stored procedure
我写了一长串存储过程来更新一些表,完成后我意识到这个存储过程的大部分彼此非常相似..只有少数字段发生变化
然后我想制作一个存储过程,这就是我所做的:
CREATE PROCEDURE dbo.Save_All
(
@UID nvarchar(100) = NULL, --All
@Table nvarchar(40) = NULL, --All
@ID int = 0, --All
...
@SubCategory nvarchar(50) = NULL, -- Ticker
@Link nvarchar(300) = NULL -- Ticker
)
AS
SET NOCOUNT ON;
BEGIN
DECLARE @S nvarchar(max)='',
@P nvarchar(max)='',
@cols1 nvarchar(max)='',
@cols2 nvarchar(max)='',
@cols3 nvarchar(max)=''
SELECT @cols1= ISNULL(@cols1 + ',','') + QUOTENAME(name)
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID' Order by colID) AS Columns;
SELECT @cols2= ISNULL(@cols2 + ',','') + '@_' + name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID' Order by colID) AS Columns;
SELECT @cols3= ISNULL(@cols3 + ',','') + QUOTENAME(name)+'=@_'+ name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID' Order by colID) AS Columns;
SELECT @cols1 = STUFF(@cols1, 1, 1, '');
SELECT @cols2 = STUFF(@cols2, 1, 1, '');
SELECT @cols3 = STUFF(@cols3, 1, 1, '');
IF (@ID=0 OR @ID is null)
SET @S = N'INSERT INTO @_Table ('+ @cols1 + ') VALUES ('+@cols2+')'
ELSE
SET @S = N' UPDATE @_Table SET ' +@cols3 +' WHERE ID=@_ID'
--PRINT @S
SET @P= '@_UID nvarchar(100),
@_Table nvarchar(40),
@_ID int,
...
@_SubCategory nvarchar(50),
@_Link nvarchar(300)'
EXEC sp_executesql @S,@P,@UID,@Table,@ID,...,@SubCategory,@Link
END
SET NOCOUNT OFF
但是,尽管参数列表很长(我在示例中修改了大部分参数),但它并未包括所有表的所有字段,因此 return 在许多情况下会出错..
解决方案是在@cols1/2/3 中只包含定义为参数的字段.. 或者将相对@_xx
设置为空
但这超出了我目前的知识..
顺便说一下.. 存储过程呢?它包含哪些不可接受的错误?
谢谢!
乔
好吧,我找到了解决方案,而且比想象的要容易..
感动
@P定义在上面并添加
SET @P= '...'
在顶部并添加
AND CHARINDEX('@_'+name+' ',@P)>0
根据规则创建 3
@cols
总计:
CREATE PROCEDURE dbo.Save_All
(
@UID nvarchar(100) = NULL, --All
@Table nvarchar(40) = NULL, --All
@ID int = 0, --All
...
@SubCategory nvarchar(50) = NULL, -- Ticker
@Link nvarchar(300) = NULL -- Ticker
)
AS
SET NOCOUNT ON;
BEGIN
DECLARE @S nvarchar(max)='',
@P nvarchar(max)='',
@cols1 nvarchar(max)='',
@cols2 nvarchar(max)='',
@cols3 nvarchar(max)=''
SET @P= '@_UID nvarchar(100),
@_Table nvarchar(40),
@_ID int,
...
@_SubCategory nvarchar(50),
@_Link nvarchar(300)'
SELECT @cols1= ISNULL(@cols1 + ',','') + QUOTENAME(name)
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID'
AND CHARINDEX('@_'+name+' ',@P)>0 Order by colID) AS Columns;
SELECT @cols2= ISNULL(@cols2 + ',','') + '@_' + name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID'
AND CHARINDEX('@_'+name+' ',@P)>0Order by colID) AS Columns;
SELECT @cols3= ISNULL(@cols3 + ',','') + QUOTENAME(name)+'=@_'+ name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID'
AND CHARINDEX('@_'+name+' ',@P)>0Order by colID) AS Columns;
SELECT @cols1 = STUFF(@cols1, 1, 1, '');
SELECT @cols2 = STUFF(@cols2, 1, 1, '');
SELECT @cols3 = STUFF(@cols3, 1, 1, '');
IF (@ID=0 OR @ID is null)
SET @S = N'INSERT INTO @_Table ('+ @cols1 + ') VALUES ('+@cols2+')'
ELSE
SET @S = N' UPDATE @_Table SET ' +@cols3 +' WHERE ID=@_ID'
--PRINT @S
EXEC sp_executesql @S,@P,@UID,@Table,@ID,...,@SubCategory,@Link
END
SET NOCOUNT OFF
好吧,有点粗糙..当然有更好的方法来构建它,但到目前为止..似乎效果很好
感谢大家阅读!
乔
我写了一长串存储过程来更新一些表,完成后我意识到这个存储过程的大部分彼此非常相似..只有少数字段发生变化
然后我想制作一个存储过程,这就是我所做的:
CREATE PROCEDURE dbo.Save_All
(
@UID nvarchar(100) = NULL, --All
@Table nvarchar(40) = NULL, --All
@ID int = 0, --All
...
@SubCategory nvarchar(50) = NULL, -- Ticker
@Link nvarchar(300) = NULL -- Ticker
)
AS
SET NOCOUNT ON;
BEGIN
DECLARE @S nvarchar(max)='',
@P nvarchar(max)='',
@cols1 nvarchar(max)='',
@cols2 nvarchar(max)='',
@cols3 nvarchar(max)=''
SELECT @cols1= ISNULL(@cols1 + ',','') + QUOTENAME(name)
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID' Order by colID) AS Columns;
SELECT @cols2= ISNULL(@cols2 + ',','') + '@_' + name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID' Order by colID) AS Columns;
SELECT @cols3= ISNULL(@cols3 + ',','') + QUOTENAME(name)+'=@_'+ name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID' Order by colID) AS Columns;
SELECT @cols1 = STUFF(@cols1, 1, 1, '');
SELECT @cols2 = STUFF(@cols2, 1, 1, '');
SELECT @cols3 = STUFF(@cols3, 1, 1, '');
IF (@ID=0 OR @ID is null)
SET @S = N'INSERT INTO @_Table ('+ @cols1 + ') VALUES ('+@cols2+')'
ELSE
SET @S = N' UPDATE @_Table SET ' +@cols3 +' WHERE ID=@_ID'
--PRINT @S
SET @P= '@_UID nvarchar(100),
@_Table nvarchar(40),
@_ID int,
...
@_SubCategory nvarchar(50),
@_Link nvarchar(300)'
EXEC sp_executesql @S,@P,@UID,@Table,@ID,...,@SubCategory,@Link
END
SET NOCOUNT OFF
但是,尽管参数列表很长(我在示例中修改了大部分参数),但它并未包括所有表的所有字段,因此 return 在许多情况下会出错..
解决方案是在@cols1/2/3 中只包含定义为参数的字段.. 或者将相对@_xx
设置为空但这超出了我目前的知识..
顺便说一下.. 存储过程呢?它包含哪些不可接受的错误?
谢谢! 乔
好吧,我找到了解决方案,而且比想象的要容易..
感动 @P定义在上面并添加
SET @P= '...'
在顶部并添加
AND CHARINDEX('@_'+name+' ',@P)>0
根据规则创建 3
@cols
总计:
CREATE PROCEDURE dbo.Save_All
(
@UID nvarchar(100) = NULL, --All
@Table nvarchar(40) = NULL, --All
@ID int = 0, --All
...
@SubCategory nvarchar(50) = NULL, -- Ticker
@Link nvarchar(300) = NULL -- Ticker
)
AS
SET NOCOUNT ON;
BEGIN
DECLARE @S nvarchar(max)='',
@P nvarchar(max)='',
@cols1 nvarchar(max)='',
@cols2 nvarchar(max)='',
@cols3 nvarchar(max)=''
SET @P= '@_UID nvarchar(100),
@_Table nvarchar(40),
@_ID int,
...
@_SubCategory nvarchar(50),
@_Link nvarchar(300)'
SELECT @cols1= ISNULL(@cols1 + ',','') + QUOTENAME(name)
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID'
AND CHARINDEX('@_'+name+' ',@P)>0 Order by colID) AS Columns;
SELECT @cols2= ISNULL(@cols2 + ',','') + '@_' + name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID'
AND CHARINDEX('@_'+name+' ',@P)>0Order by colID) AS Columns;
SELECT @cols3= ISNULL(@cols3 + ',','') + QUOTENAME(name)+'=@_'+ name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(@Table) and name<>'ID'
AND CHARINDEX('@_'+name+' ',@P)>0Order by colID) AS Columns;
SELECT @cols1 = STUFF(@cols1, 1, 1, '');
SELECT @cols2 = STUFF(@cols2, 1, 1, '');
SELECT @cols3 = STUFF(@cols3, 1, 1, '');
IF (@ID=0 OR @ID is null)
SET @S = N'INSERT INTO @_Table ('+ @cols1 + ') VALUES ('+@cols2+')'
ELSE
SET @S = N' UPDATE @_Table SET ' +@cols3 +' WHERE ID=@_ID'
--PRINT @S
EXEC sp_executesql @S,@P,@UID,@Table,@ID,...,@SubCategory,@Link
END
SET NOCOUNT OFF
好吧,有点粗糙..当然有更好的方法来构建它,但到目前为止..似乎效果很好
感谢大家阅读! 乔