[英]SQL dynamic columns and Update multiple columns
I have a table UserPermission
which has a number of columns of TINYINT
type. 我有一个表
UserPermission
,它有许多TINYINT
类型的列。 eg Read, Write, Update, Delete, Access etc. 例如,读,写,更新,删除,访问等
I get three parameters in the stored procedure: @UserId, @ColNames, @ColValues
where @ColNames
and @ColValues
are comma separated values. 我在存储过程中得到三个参数:
@UserId, @ColNames, @ColValues
其中@ColNames
和@ColValues
是逗号分隔值。
How can I insert or update the table row (if already exists) with the passed column names and corresponding values. 如何使用传递的列名和相应的值插入或更新表行(如果已存在)。
I try to write the dynamic query which runs fine for INSERT
but I was unable to write the UPDATE
query dynamically with each column and its value to be concatenate. 我试着写它运行的罚款动态查询
INSERT
,但我无法写UPDATE
每列,并将其值动态查询是串连。
Any response would be appreciated 任何回应将不胜感激
Thanks in advance. 提前致谢。
This is a somewhat dirty way to do what you require. 这是一种有点肮脏的方式来做你需要的。 However, if you create the following Stored Procedure:
但是,如果您创建以下存储过程:
CREATE FUNCTION [dbo].[stringSplit]
(
@String NVARCHAR(4000),
@Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
FROM Split
)
You can then use that Procedure to join the data together: 然后,您可以使用该过程将数据连接在一起:
DECLARE @TotalCols INT
DECLARE @TotalVals INT
SET @TotalCols = (
SELECT COUNT(ID) AS Total
FROM dbo.stringSplit('department, teamlead', ',')
);
SET @TotalVals = (
SELECT COUNT(ID) AS Total
FROM dbo.stringSplit('IT, Bob', ',')
);
IF @TotalCols = @TotalVals
BEGIN
IF OBJECT_ID('tempdb..#temptable') IS NOT NULL
DROP TABLE #temptable
CREATE TABLE #temptable (
ColName VARCHAR(MAX) NULL
,ColValue VARCHAR(MAX) NULL
)
INSERT INTO #temptable
SELECT a.DATA
,b.DATA
FROM dbo.stringSplit('department, teamlead', ',') AS a
INNER JOIN dbo.stringSplit('IT, Bob', ',') AS b ON a.Id = b.Id
SELECT *
FROM #temptable;
END
It's not very efficient, but it will bring you the desired results. 它不是很有效,但会带给你理想的效果。
You can then use the temp table to update, insert and delete as required. 然后,您可以根据需要使用临时表进行更新,插入和删除。
Instead of having a comma delimited list I would create a separate parameter for each Column and make its default value to NULL and in the code update nothing if its null or insert 0. Something like this.... 我没有逗号分隔列表,而是为每个列创建一个单独的参数,并将其默认值设置为NULL,如果为null或插入0,则代码更新中没有任何内容。这样的事情....
CREATE PROCEDURE usp_UserPermissions
@UserID INT
,@Update INT = NULL --<-- Make default values NULL
,@Delete INT = NULL
,@Read INT = NULL
,@Write INT = NULL
,@Access INT = NULL
AS
BEGIN
SET NOCOUNT ON;
Declare @t TABLE (UserID INT, [Update] INT,[Read] INT
,[Write] INT,[Delete] INT,[Access] INT)
INSERT INTO @t (Userid, [Update],[Read],[Write],[Delete],[Access])
VALUES (@UserID , @Update , @Read, @Write , @Delete, @Access)
IF EXISTS (SELECT 1 FROM UserPermission WHERE UserID = @UserID)
BEGIN
UPDATE up -- Only update if a value was provided else update to itself
SET up.[Read] = ISNULL(t.[Read] , up.[Read])
,up.[Write] = ISNULL(t.[Write] , up.[Write])
,up.[Update] = ISNULL(t.[Update] , up.[Update])
,up.[Delete] = ISNULL(t.[Delete] , up.[Delete])
,up.[Access] = ISNULL(t.[Access] , up.[Access])
FROM UserPermission up
INNER JOIN @t t ON up.UserID = t.UserID
END
ELSE
BEGIN
-- if already no row exists for that User add a row
-- If no value was passed for a column add 0 as default
INSERT INTO UserPermission (Userid, [Update],[Read],[Write],[Delete],[Access])
SELECT Userid
, ISNULL([Update], 0)
, ISNULL([Read], 0)
, ISNULL([Write], 0)
, ISNULL([Delete], 0)
, ISNULL([Access], 0)
FROM @t
END
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.