2012-02-29 5 views
1

Я хочу разбить столбец строк, скажем, «99 кристальных пружин дороги» и получить только 2 слова (99 и кристалл) соответственно и обновить 99 до одной колонки и кристалла в другой столбец другой таблицы. Как это сделать, используя charindex и подстроку?SQL SERVER 2008 R2 string split

+1

Каковы правила, почему вы хотите только 99 и кристалл? Потому что это первые два слова? – kaj

ответ

1

Вот некоторые примеры кода на том, как это сделать ...

Во-первых, создать эту функцию:

CREATE FUNCTION [dbo].[GetStringPart] 
(@fullString varchar(200), @pos tinyint) 
RETURNS VARCHAR(200) -- return_data_type. 
AS 
BEGIN 
    IF @pos IS NULL OR @pos <= 0 
     SET @pos = 1 

    declare @secondPart varchar(200),@firstPart varchar(200),@output varchar(200) 
    declare @firstSpace int, @secondSpace int 

    set @firstSpace = CHARINDEX(' ', @fullString) 

    IF @firstSpace <= 0 
     RETURN '' 
    ELSE IF @pos = 1 
     BEGIN 
      SET @output = LTRIM(RTRIM(SUBSTRING(@fullString, 1, @firstSpace))) 
     END 
    ELSE 
     BEGIN 
      SET @secondSpace = CHARINDEX(' ', @fullString, CHARINDEX(' ', @fullString)+1) - CHARINDEX(' ', @fullString)+1 
      IF @secondSpace <= 0 
       SET @secondSpace = LEN(@fullString) - @firstSpace + 1 
      SET @output = LTRIM(RTRIM(SUBSTRING(@fullString, @firstSpace, @secondSpace))) 

     END 

    RETURN @Output 
END 

GO 

Затем вы можете использовать его как это:

declare @origTable table(name varchar(100)) 
insert into @origTable (name) values ('99 crystal springs road') 

declare @newTable table(col1 varchar(100), col2 varchar(100)) 

INSERT INTO @newTable (col1, col2) 
SELECT dbo.GetStringPart(name, 1), dbo.GetStringPart(name, 2) FROM @origTable 

select * from @newTable 
+0

Я получаю «Неверный параметр длины, переданный функции LEFT или SUBSTRING». – rsDesigner

+0

У меня есть таблица с записями адресов, как указано выше. разделить адрес и получить только первые два слова и сбросить в другую таблицу. Надеюсь, я правильно объясню эту проблему. – rsDesigner

+0

Причина этой ошибки была, вероятно, в том, что у вас не было 2 пробелов в каждой строке. Я бы создал функцию, а затем вызвал эту функцию. Функция может иметь некоторую логику для проверки этого второго пространства. Я пересмотрел свой ответ выше. –

1

Предполагая что вы выбираете «99» и «кристалл» только потому, что это первые два слова ...

Вы можете сделать это i на один шаг, но для удобства чтения решения я отделил из

declare @sourceAddresses table 
(
    address varchar(100) 
) 

declare @split table 
(
    address varchar(100), 
    firstDelimiter int, 
    secondDelimiter int 
) 

declare @table table 
(
    part1 varchar(20), 
    part2 varchar(20) 
) 

insert into @sourceAddresses (address) values ('99 crystal springs road') 
insert into @sourceAddresses (address) values ('100 elsewhere road') 


insert into @split (address, firstDelimiter) 
select address, charindex(' ', address) 
from @sourceAddresses 

update @split 
set secondDelimiter = charindex(' ', address, (firstDelimiter+1)) 
where firstDelimiter > -1 

insert into @table (part1, part2) 
select substring(address, 0, firstDelimiter), substring(address, (firstDelimiter+1), (secondDelimiter-firstDelimiter)) 
from @split 
where firstDelimiter > -1 
    and secondDelimiter > -1 

select * from @table 
+0

мой код «Вставить в @ таблицу»: – rsDesigner

+0

Обновленное решение для использования исходной таблицы адресов, а не только одного адреса переменной – kaj

+0

Это работает для примера, но когда я использую фактические данные длиной в 90 символов, он выдает длину Invalide передается функции LEFT или SUBSTRING. Возможно, из-за NULLS или EMPTY? ИЛИ Если есть только два слова типа «9-й улицы»? – rsDesigner

1

Может быть что-то вроде этого:

Сначала нужно создать функцию, которая получает часть строки:

CREATE FUNCTION dbo.GetStringPart (@sep char(1), @s varchar(512),@pos int) 
RETURNS VARCHAR(200) 
AS 
BEGIN 
    DECLARE @output VARCHAR(200) 
    ;WITH Pieces(pn, start, stop) AS (
     SELECT 1, 1, CHARINDEX(@sep, @s) 
     UNION ALL 
     SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1) 
     FROM Pieces 
     WHERE stop > 0 
    ) 
    SELECT 
     @output=SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) 
    FROM Pieces 
    WHERE [email protected] 
    RETURN @Output 
END 

GO 

Тогда вы можете легко сделать это:

DECLARE @origalTable TABLE(name VARCHAR(100)) 
INSERT INTO @origalTable 
VALUES('99 crystal springs road') 

DECLARE @newTable TABLE(col1 VARCHAR(100), col2 VARCHAR(100)) 

INSERT INTO @newTable (col1, col2) 
SELECT dbo.GetStringPart(' ',name, 1), dbo.GetStringPart(' ',name, 2) FROM @origalTable 

SELECT * FROM @newTable 
DROP FUNCTION dbo.GetStringPart 
Смежные вопросы