我有一个表结构,其中包含一个标识符列和一个包含已删除字符串的列。我想要实现的是将已删除的字符串插入到新表中,作为拆分字符串中每个值的单独记录。
源表的表结构如下:
CREATE TABLE tablea(personID VARCHAR(8), delimStr VARCHAR(100))
一些示例数据:
INSERT INTO tablea (personID, delimStr) VALUES ('A001','Monday, Tuesday')
INSERT INTO tablea (personID, delimStr) VALUES ('A002','Monday, Tuesday, Wednesday')
INSERT INTO tablea (personID, delimStr) VALUES ('A003','Monday')
我的目的地表格如下:
CREATE TABLE tableb(personID VARCHAR(8), dayName VARCHAR(10))
我正在尝试创建一个存储过程来进行插入,我的SP到目前为止看起来像:
CREATE PROCEDURE getTKWorkingDays
@pos integer = 1
, @previous_pos integer = 0
AS
BEGIN
DECLARE @value varchar(50)
, @string varchar(100)
, @ttk varchar(8)
WHILE @pos > 0
BEGIN
SELECT @ttk = personID
, @string = delimStr
FROM dbo.tablea
SET @pos = CHARINDEX(',', @string, @previous_pos + 1)
IF @pos > 0
BEGIN
SET @value = SUBSTRING(@string, @previous_pos + 1, @pos - @previous_pos - 1)
INSERT INTO dbo.tableb ( personID, dayName ) VALUES ( @ttk, @value )
SET @previous_pos = @pos
END
END
IF @previous_pos < LEN(@string)
BEGIN
SET @value = SUBSTRING(@string, @previous_pos + 1, LEN(@string))
INSERT INTO dbo.tableb ( tkinit, dayName ) VALUES ( @ttk, @value )
END
END
插入的数据(原始表中170个左右只有1个记录,在分割了被删除的字符串之后,应该会在新表中产生大约600个左右的记录),这是不正确的。
我期望使用上面的示例数据看到:
personID dayName
A001 Monday
A001 Tuesday
A002 Monday
A002 Tuesday
A002 Wednesday
A003 Monday
是否有人能够指出任何资源或确定我哪里出错,以及如何使此查询有效?
数据库是MS SQL Server 2000。
我提前感谢您提供的任何帮助。
马特
答案 0 :(得分:1)
你的SELECT
语句让“下一个”的人没有WHERE
子句,所以我不确定SQL Server如何知道移动到下一个人。如果这是一次性任务,为什么不使用游标?
CREATE TABLE #n(n INT PRIMARY KEY);
INSERT #n(n) SELECT TOP 100 number FROM [master].dbo.spt_values
WHERE number > 0 GROUP BY number ORDER BY number;
DECLARE
@PersonID VARCHAR(8), @delimStr VARCHAR(100),
@str VARCHAR(100), @c CHAR(1);
DECLARE c CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR SELECT PersonID, delimStr FROM dbo.tablea;
OPEN c;
FETCH NEXT FROM c INTO @PersonID, @delimStr;
SET @c = ',';
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @delimStr = @c + @delimStr + @c;
-- INSERT dbo.tableb(tkinit, [dayName])
SELECT @PersonID, LTRIM(SUBSTRING(@delimStr, n+1, CHARINDEX(@c, @delimStr, n+1)-n-1))
FROM #n AS n
WHERE n.n <= LEN(@delimStr) - 1
AND SUBSTRING(@delimStr, n.n, 1) = @c;
FETCH NEXT FROM c INTO @PersonID, @delimStr;
END
CLOSE c;
DEALLOCATE c;
DROP TABLE #n;
如果您create a permanent numbers table(显然超过100行),您可以将其用于多种用途。您可以创建一个拆分函数,允许您在没有游标的情况下执行上述操作(好,没有显式游标)。但是,当你最终离开SQL Server 2000时,这可能会效果最好。较新版本的SQL Server具有更灵活和可扩展的方式来执行拆分和连接。