更新包含由|分隔的列表的列使用sql

时间:2013-05-01 12:39:25

标签: sql sql-server tsql

我有一个名为hr_Folders的表,其中包含以下信息:

FolderId    FolderName  EmployeeId  NumberOfEntries IsDeleted   
1            Folder 1      9                 1              0   
2            Folder 2      9                 1              0   
3            Folder 3      9                 1              0   

还有另一个表hr_EmployeeSavedRegistrants,其中folderids保存为|这样的分隔列表:

ID  EmployeeID  RegistrantID    FolderID    
44    9           4           1|2   
45    9           5           1|3       
46    9           6           2

我想创建一个存储过程,当我传递folderid和employeeid时,它会从hr_folder中删除该文件夹,然后相应地更新hr_EmployeeSavedRegistrants表的FolderId列(从folderid列列表中删除folderid,如果hr_EmployeeSavedRegistrants中有一个folderid,然后删除该行,如hr_EmployeeSavedRegistrants中的第3行

到目前为止编写的代码是:

CREATE PROC GetResumeCountInfolder

@Folder int

AS

DECLARE @FolderIDs VARCHAR(100)
SELECT @FolderIDs = FolderID from hr_EmployeeSavedRegistrants
where deleted = 0
and EmployeeID= 9

请建议如何操作

由于

1 个答案:

答案 0 :(得分:0)

这是一个给出你的表结构的解决方案,但是,我同意Mahmoud - 你真的应该规范你的表。创建一个名为hr_EmployeeFolders的新表,其中EmployeeId和FolderId作为您的两个字段。然后,您可以存储1-n个员工和文件夹。这种方式更容易维护。

但是,鉴于您当前的情况,这样的事情应该有效:

create proc updatefolder 
  @FolderId int, @EmployeeId int
as
begin
  update hr_Folders 
  set isdeleted = 1
  where folderId = @folderId and employeeId = @employeeId

  update hr_EmployeeSavedRegistrants 
  set FolderId = replace(replace(folderId, @FolderId, ''),'||','|')
  where employeeId = @employeeId

  update hr_EmployeeSavedRegistrants 
  set FolderId =
    case 
      when left(FolderId,1) = '|' then right(folderId, len(folderId) - 1)
      when right(FolderId,1) = '|' then left(folderId, len(folderId) - 1)
      else FolderId
    end
  where employeeId = @employeeId
end

SQL Fiddle Demo

还有一些其他选项可以拆分列表并重新创建,但这是我能想到的最快的选项。第一个更新语句更新文件夹表中的已删除列。第二个更新语句从EmployeeSavedRegistrants表中删除文件夹ID,以及任何潜在的双管道实例。最终更新语句删除任何开始或尾随管道。