2013-05-01 77 views
1

我正在寻找MSSQL 2005触发器的正确​​语法,该触发器将拆分一列的值并更新其他四列。需要SQL触发器根据破折号分隔符拆分字符串

  • 数据库:TestDB
  • 表:UploadAppTable

之前

|OriginalFile     | EmployeeID | EmployeeTitle | Location | ApplicationID 
|0146291-ITDCCT-02-1367413404 |   |    |   | 

我需要什么,如果以下。当新记录被插入时,我需要SQL触发器来更新表格。

输出

|OriginalFile     | EmployeeID | EmployeeTitle | Location | ApplicationID 
|0146291-ITDCCT-02-1367413404 | 0146291 | ITDCCT  | 02  | 1367413404 

任何帮助将不胜感激。

+0

说实话,我从来没有写过更新声明,将更新多列。所以我需要建议,所以我可以尝试一些。我还没有尝试过任何东西。 – user2066533 2013-05-01 15:25:54

+0

看起来像“CHARINDEX”是要用分隔符分割字符串的方法。我只是不知道正确的语法。我还需要将其添加到SQL触发器。 – user2066533 2013-05-01 15:36:43

+2

*** SQL ***只是*结构化查询语言* - 许多数据库系统使用的语言,但不是数据库产品...类似于触发器的事物是高度**特定于供应商的 - 因此我们真的需要了解您正在使用的**数据库系统**(以及哪个版本)(请相应地更新标签).... – 2013-05-01 15:50:09

回答

0

分隔这些值可以使用dbo.SplitStrings_CTE功能

CREATE FUNCTION dbo.SplitStrings_CTE(@List nvarchar(max), @Delimiter nvarchar(1)) 
RETURNS @returns TABLE(val nvarchar(max), [level] int, PRIMARY KEY CLUSTERED([level])) 
AS 
BEGIN 
;WITH cte AS 
(
    SELECT SUBSTRING(@List, 0, CHARINDEX(@Delimiter, @List)) AS val, 
     CAST(STUFF (@List + @Delimiter, 1, CHARINDEX(@Delimiter, @List), '') AS nvarchar(max)) AS stval, 
     1 AS [level] 
    UNION ALL 
    SELECT SUBSTRING(stval, 0, CHARINDEX(@Delimiter, stval)), 
     CAST(STUFF (stval, 1, CHARINDEX(@Delimiter, stval), '') AS nvarchar(max)), 
     [level] + 1 
    FROM cte 
    WHERE stval != '' 
) 
    INSERT @returns 
    SELECT REPLACE(val, ' ', '') AS val, [level] 
    FROM cte 
    RETURN 
END 

创建功能后,使用UPDATE语句

;WITH cte AS 
( 
    SELECT t.OriginalFile, t.EmployeeID, t.EmployeeTitle, t.Location, t.ApplicationID, 
     NewEmployeeID = MAX(CASE WHEN o.level = 1 THEN o.val END) OVER(), 
     NewEmployeeTitle = MAX(CASE WHEN o.level = 2 THEN o.val END) OVER(), 
     NewLocation = MAX(CASE WHEN o.level = 3 THEN o.val END) OVER(), 
     NewApplicationID = MAX(CASE WHEN o.level = 4 THEN o.val END) OVER() 
    FROM dbo.UploadAppTable t CROSS APPLY dbo.SplitStrings_CTE(t.OriginalFile, '-') o 
) 
    UPDATE cte 
    SET EmployeeID = NewEmployeeID, 
     EmployeeTitle = NewEmployeeTitle, 
     Location = NewLocation, 
     ApplicationID = NewApplicationID 

演示上SQLFiddle

或UPDATE语句的多重更新

;WITH cte AS 
( 
    SELECT t.OriginalFile, t.EmployeeID, t.EmployeeTitle, t.Location, t.ApplicationID, 
     NewEmployeeID = MAX(CASE WHEN o.level = 1 THEN o.val END) OVER(PARTITION BY t.OriginalFile), 
     NewEmployeeTitle = MAX(CASE WHEN o.level = 2 THEN o.val END) OVER(PARTITION BY t.OriginalFile), 
     NewLocation = MAX(CASE WHEN o.level = 3 THEN o.val END) OVER(PARTITION BY t.OriginalFile), 
     NewApplicationID = MAX(CASE WHEN o.level = 4 THEN o.val END) OVER(PARTITION BY t.OriginalFile) 
    FROM dbo.UploadAppTable t CROSS APPLY dbo.SplitStrings_CTE(t.OriginalFile, '-') o 
) 
    UPDATE cte 
    SET EmployeeID = NewEmployeeID, 
     EmployeeTitle = NewEmployeeTitle, 
     Location = NewLocation, 
     ApplicationID = NewApplicationID 

演示SQLFiddle

+0

嗨@Alexander Fedorenko非常感谢您的帮助。功能和更新声明的工作,但现在我有问题,每当添加一个新的条目。它会更新我以前的最新作品。尝试了[SQLFiddle](http://sqlfiddle.com/#!3/25a7e/1/2) – user2066533 2013-05-02 18:56:41

+1

它的工作原理,我只需要在我的FROM后添加一个where语句。 – user2066533 2013-05-02 20:12:23

+0

欢迎来到StackOverflow!如果您需要多个UPDATE语句,请将PARTITION BY t.OriginalFile表达式添加到OVER()子句中。答复已更新;) – 2013-05-03 04:39:45

0

你想要做类似OriginalFile.Split('-')的东西,对不对?可悲的是,在SQL Server中没有可用的内部字符串分割,您将不得不推出自己的。随后,Erland Sommarskog为每个人都省下了不必担心的问题,因为有些优秀的文章可以找到,您可以找到here

+0

谢谢@Steve Pettifer。我会在你上一篇文章中关注这个链接。我想知道你将如何处理串联的对立面。将破折号分隔的字符串拆分成数据行。 – user2066533 2013-05-01 16:09:55

+0

错......这就是我刚发布的!级联很容易,但这里没有关系。你想根据给定的分隔符来分割一个字符串。我的一小块伪​​代码('OriginalFile.Split(' - ')')实际上是有效的.Net语法,它证明了我相信你想要做的事情。我的观点是,在T-SQL中没有内在的功能,也没有与数组等价的功能。因此,您必须创建自己的函数来分割字符串并返回值或使用诸如表值参数之类的东西。 – 2013-05-01 16:20:45