2013-08-15 5 views
1

Во время недавнего восстановления и возникшей проблемы, которая может быть или не быть раньше, но теперь, когда я знаю об этом, мне было поручено разработать решение для нее. Обычно мы записываем данные в несколько имен столбцов для каждой строки, однако я обнаружил, что все поля переходят в столбец переполнения. Ниже приведен пример того, что у нас есть.разделить один столбец на несколько именованных столбцов

Столбцы мы должны иметь данные в:

fldDate - fldName - fldPhoneNumber - fldTransactionID - fldOverflow  
8/15/13 - John Smith - 1012023344  - 123456789  - Null 

Что мы получаем:

fldDate - fldName - fldPhoneNumber - fldTransactionID - fldOverflow 
8/15/13 - null  - null   - null    - fldName="John Smith", fldPhoneNumber="1012023344", fldTransactionID="123456789" 

Что мне нужно:

мне нужно найти способ, чтобы получить данные fldOverflow поля вернитесь в правильные поля. Любая помощь будет принята с благодарностью.

ответ

0

Есть многочисленные функции там для разделения разделителями поля на несколько столбцов, так что это вариант, вы можете также использовать COALESCE() и манипуляции со строками, что-то вроде:

SELECT fldDate 
     , fldName = COALESCE(fldName, SUBSTRING(fldOverflow,CHARINDEX('fldName="',fldOverflow)+9,CHARINDEX(', fldPhone',fldOverflow)-CHARINDEX('fldName="',fldOverflow)-10)) 
     , fldPhoneNumber 
     , fldTransactionID 
     , fldOverflow 
FROM Table 
0

Я бы преобразовать значения fldOverflow в XML а затем я хотел бы использовать UPDATE таким образом:

DECLARE @MyTable TABLE(
    fldName   NVARCHAR(50), 
    fldPhoneNumber VARCHAR(20), 
    fldTransactionID INT, 
    fldOverflow  NVARCHAR(4000) 
); 
INSERT INTO @MyTable (fldOverflow) 
VALUES (N'fldName="John Smith", fldPhoneNumber="1012023344", fldTransactionID="123456789"'); 

PRINT 'Before:' 
SELECT * 
FROM @MyTable; 

-- I would use, also, transactions thus 
-- BEGIN TRANSACTION 
UPDATE x 
SET  fldName   =z.fldName, 
     fldPhoneNumber =z.fldPhoneNumber, 
     fldTransactionID=z.fldTransactionID, 
     fldOverflow  =NULL 
-- OUTPUT deleted.fldName AS OldfldName,inserted.fldName AS NewfldName, ... 
FROM @MyTable x 
CROSS APPLY 
(
    SELECT y.XmlFragment.value('(/row/@fldName)[1]','NVARCHAR(50)') AS fldName, 
      y.XmlFragment.value('(/row/@fldPhoneNumber)[1]','VARCHAR(20)') AS fldPhoneNumber, 
      y.XmlFragment.value('(/row/@fldTransactionID)[1]','INT') AS fldTransactionID 
    FROM 
    (
     SELECT CONVERT(XML,'<row '+REPLACE(x.fldOverflow,',', ' ')+' />') AS XmlFragment 
    ) y 
) z 
WHERE x.fldOverflow IS NOT NULL; 
-- ROLLBACK TRANSACTION 
-- -- COMMIT TRANSACTION 

PRINT 'After:' 
SELECT * 
FROM @MyTable; 

Результаты:

Before: 
fldName  fldPhoneNumber fldTransactionID fldOverflow 
----------- --------------- ---------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
NULL  NULL   NULL    fldName="John Smith", fldPhoneNumber="1012023344", fldTransactionID="123456789" 

After: 
fldName  fldPhoneNumber fldTransactionID fldOverflow 
----------- --------------- ---------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
John Smith 1012023344  123456789  NULL 

Edit 1:

SELECT x.fldName AS OldfldName,z.fldName AS NewfldName, ... 
FROM @MyTable x 
CROSS APPLY 
(
    SELECT y.XmlFragment.value('(/row/@fldName)[1]','NVARCHAR(50)') AS fldName, 
      y.XmlFragment.value('(/row/@fldPhoneNumber)[1]','VARCHAR(20)') AS fldPhoneNumber, 
      y.XmlFragment.value('(/row/@fldTransactionID)[1]','INT') AS fldTransactionID 
    FROM 
    (
     SELECT CONVERT(XML,'<row '+REPLACE(x.fldOverflow,',', ' ')+' />') AS XmlFragment 
    ) y 
) z 
WHERE x.fldOverflow IS NOT NULL; 
+0

Это здорово. Однако я не мастер sql, поэтому простите меня, если я уже усложняю это. У меня около 3 миллионов строк, которые мне нужно обновить, как я могу получить значения для работы с этим запросом? –

+0

Я тоже. Если вы хотите увидеть, как разложить значения 'fldOverflow' в' fldName', 'fldPhoneNumber' и т. Д., Вы можете использовать UPDATE с OUTPUT (см. Инструкцию UPDATE) или инструкцию SELECT вместо UPDATE (см. Редактировать 1). –

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