简体   繁体   English

SQL动态列和更新多列

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM