2012-06-22 5 views
2
COMMSTR1-NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C 

Я хочу, чтобы отделить вышеуказанную строку как (Required Output)Как отделить строку на основе условия?

col1  col2   col3  col4   col5 col6 
COMMSTR1 NAC-NAM-P-C FCPANAM1 NAC-NAM-P-C CHAZEL1 NAT-CBM-P-C 

Я попытался это.

SELECT Contact_assg_list_src, 
Contact_Assg_List_Src = 
(
case WHEN Contact_Assg_List_Src IS NOT NULL and Contact_Assg_List_Src <> '' 
then left(Contact_Assg_List_Src,patindex('%[-]%',Contact_Assg_List_Src)-1) 
ELSE Contact_Assg_List_Src 
END), 
(case WHEN Contact_Assg_List_Src IS NOT NULL and Contact_Assg_List_Src <> '' 
then substring(Contact_Assg_List_Src,(Patindex('%[-]%',Contact_Assg_List_Src + ' ')-1),len(Contact_Assg_List_Src)) 
ELSE Contact_Assg_List_Src 
END) 
from dbo.FBMSRAW; 

Что дает мне выход, как

col1   col2 
COMMSTR1  NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C 

Как я могу проверить, является ли строка имеет пространство, то отделить строку, основанную на том, чтобы получить требуемую мощность?

+1

TSQL не большой инструмент для манипулирования строками. Есть ли причина, по которой вы пытаетесь сделать это на сервере? –

+0

@Damien_The_Unbeliever да, потому что моя работа - очистка данных, поэтому я не могу использовать ничего, кроме этого. –

+0

столбцы фиксированы, я имею в виду максимальное количество пробелов там? можете ли вы считать это до 50? –

ответ

0

Если вы хотите сделать это эффективно на SQL-сервере, я бы посоветовал использовать функцию CLR.

Но если вы должны сделать это в T-SQL, эта функция будет достичь его (медленно, и все более неэффективным способом)

create function SplitString 
    (
     @splitchar char(1), 
     @string varchar(500), 
     @index int 
    ) 
    returns varchar(500) 
    as 
    begin 

    declare @split int, @start int, @loop bit, @i int, @ret varchar(500) 
     select @start = 0, @i = 0 
     select @split = charindex(@splitchar, @string, 0) 

     if @index>0 
      select @loop = 1 
     else 
      select @loop = 0 

     while @loop = 1 
     begin 

      select @start = @split+1 
      select @split = charindex(@splitchar, @string, @start+1) 

      if @split = 0 
      begin 
       select @split = len(@string)+1 
      end 

      select @i = @i + 1 
      if @i = @index 
      begin 
       select @loop = 0 
      end 

     end 
     if @split>@start 
      select @ret = substring(@string, @start, @[email protected]) 
     else 
      select @ret = null 

     return @ret 
    end 

    select dbo.SplitString (' ', 'COMMSTR1-NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C', [0 based column number]) 
0

Я написал следующий сценарий, чтобы удовлетворить ваши потребности, но ваша собственная личность вам нужно добавить больше логики, понять следующий сценарий

Создать фиктивный таблицу

CREATE TABLE TBL_TEMPSTRINGS(STRCOL VARCHAR(200),COL1 VARCHAR(50), 
COL2 VARCHAR(50),COL3 VARCHAR(50)) 

значение вставки из таблицы

INSERT INTO TBL_TEMPSTRINGS 
SELECT Contact_assg_list_src From dbo.FBMSRAW 

Создайте хранимую процедуру, чтобы обновить фиктивные столбцы таблицы, она занимает свое имя таблицы в строке (почему вы можете заменить фиктивную таблицу с температурными именем таблицы, если вы использовали)

CREATE PROC SP_SPLITWRODS(@TABLENAME VARCHAR(50),@COLCOUNT INT) 
AS 
BEGIN 
    DECLARE @QRY VARCHAR(500) 

    CREATE TABLE #TBL_TEMP(STRCOL VARCHAR(200)) 
    DECLARE @STRCOL VARCHAR(200) 
    DECLARE @CURRINDEX INT 
    DECLARE @TEMP INT 
    DECLARE @COLINDEX INT 
    DECLARE @ROWID INT 
    DECLARE @STRLEN INT 
    DECLARE @TEMPVALUE VARCHAR(50) 
    DECLARE @LASTWORD BIT 
    --CURSOR FOR YOUR TEMP TABLE 
    DECLARE CUR_TEMP CURSOR LOCAL FOR SELECT STRCOL FROM #TBL_TEMP 

    --CONSTRUCT QRY FOR FILLING YOUR TABLE 
    SET @QRY='INSERT INTO #TBL_TEMP SELECT STRCOL FROM ' + @TABLENAME 

    --FILL TABLE 
    EXECUTE(@QRY) 

    OPEN CUR_TEMP 
    FETCH CUR_TEMP INTO @STRCOL 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @CURRINDEX=1 
     SET @COLINDEX=1 
     SET @LASTWORD=0 
     --GET ' ' INDEX 
     SET @TEMP=CHARINDEX(' ',@STRCOL,@CURRINDEX) 
     WHILE @TEMP > 0 
     BEGIN 
      --YOU WILL GET THE VALUE SEPERATED BY SPACE 
      SET @TEMPVALUE=SUBSTRING(@STRCOL,@CURRINDEX,@[email protected]) 

      --ADD MORE LOGIC TO UPDATE YOUR COLUMNS (YOUR EXTRA COLUMNS) 

      --CONTRUCT QRY TO UPDATE CORRESPONDING COL IN YOUR TABLE FOR THE ROW FETCHED 
      --THIS UPDATES ALL ROWS, YOU NEED TO ADD ONE WHERE CONDITION TO UPDATE THE ROW 
      SET @QRY='UPDATE ' + @TABLENAME + ' SET COL' + CAST(@COLINDEX AS VARCHAR) + '=''' + @TEMPVALUE + '''' 

      EXEC(@QRY) 

      --INCREMENT COL INDEX AFTER UPDATE OF LAST COLUMN 
      SET @[email protected]+1 

      SET @[email protected]+1 

      SET @TEMP=CHARINDEX(' ',@STRCOL,@CURRINDEX) 

      IF @TEMP=0 AND @LASTWORD=0 
      BEGIN 
       SET @TEMP=LEN(@STRCOL)+1 
       SET @LASTWORD=1 
      END 
     END 

     FETCH CUR_TEMP INTO @STRCOL 
    END 

    CLOSE CUR_TEMP 

    DEALLOCATE CUR_TEMP 

END 

Execute ваш прок

EXEC SP_SPLITWRODS 'TBL_TEMPSTRINGS',1 

посещайте обновленный фиктивная таблица

SELECT * FROM TBL_TEMPSTRINGS 

В настоящее время обновляется 3 столбца, разделенных пробелом, вам нужно добавить свою собственную логику для обновления столбцов на основе полученной строки (разделенной пробелом).

Надеется, что это помогает

0

первой функции, чтобы разделить текст

create function [dbo].[f_split] 
(
@param nvarchar(max), 
@delimiter char(1) 
) 
returns @t table (val nvarchar(max), seq int) 
as 
begin 
set @param += @delimiter 

;with a as 
(
select cast(1 as bigint) f, charindex(@delimiter, @param) t, 1 seq 
union all 
select t + 1, charindex(@delimiter, @param, t + 1), seq + 1 
from a 
where charindex(@delimiter, @param, t + 1) > 0 
) 
insert @t 
select substring(@param, f, t - f), seq from a 
option (maxrecursion 0) 
return 
end 
go 

запроса для отображения результата, предполагая, что существует не более 6 «слов»

declare @t table(txt nvarchar(500)) 

insert @t values ('COMMSTR1-NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C'), 
('t1 t2 t3 t4 t5 t6') 

select * from @t t 
outer apply 
(
select max(case when seq = 1 then val end) col1, 
     max(case when seq = 2 then val end) col2, 
     max(case when seq = 3 then val end) col3, 
     max(case when seq = 4 then val end) col4, 
     max(case when seq = 5 then val end) col5, 
     max(case when seq = 6 then val end) col6 
from dbo.f_split(t.txt, ' ') 
) b 
+0

жаль, что я удалил свой комментарий, что ваш код работает нормально, но я получаю ошибку, когда я делаю это.'SELECT Contact_assg_list_src, dbo.f_split (Contact_Assg_List_Src, '') из dbo.FBMSRAW' Ошибка:' Невозможно найти ни один столбец "dbo", либо определенную пользователем функцию или совокупность "dbo.f_split", либо имя неоднозначно. ' –

+0

Я создал функцию правильно, и ваш код работает на вашем примере. –

Смежные вопросы