Вы должны , вероятно, пересмотреть свою схему. Когда у вас есть что-то похожее на массив в одной строке, часто лучше разделить его на отдельные строки.
Но, предполагая, что вы застряли с текущей схемой, я бы просто сказал:
start transaction;
update TBL set SP8 = 0 where SP8 is null;
update TBL set SP7 = SP8 where SP7 is null;
update TBL set SP6 = SP7 where SP6 is null;
update TBL set SP5 = SP6 where SP5 is null;
update TBL set SP4 = SP5 where SP4 is null;
update TBL set SP3 = SP4 where SP3 is null;
update TBL set SP2 = SP3 where SP2 is null;
update TBL set SP1 = SP2 where SP1 is null;
commit;
(при необходимости подставляя правильный синтаксис транзакции SQL Server).
Если вы не хотите на самом деле изменять базовые данные, вы можете использовать представление, но оно, вероятно, будет отвратительным, и вы можете захотеть сделать трансформацию в любом приложении, которое у вас есть ' вместо этого используется для выполнения SQL.
Одна возможность, но я настоятельно призываю вас не делать этого, и может быть лучший способ для конкретного поставщика:
- создает представление
view8
над таблицей, которое оставляет все столбцы нетронутыми, за исключением SP8
, который становится coalesce(sp8,0)
(или любым другим эквивалентом SQL Server - SP8
, если он не равен NULL, иначе 0).
- создать представление
view7
поверх представления view8
, которое оставляет все столбцы без изменений, кроме SP7
, который становится coalesce(sp7,sp8)
.
- создать представление
view6
поверх представления view7
, которое оставляет все столбцы без изменений, кроме SP6
, который становится coalesce(sp6,sp7)
.
- бла, бла, бла.
- создать представление
view1
поверх вида view2
, которое оставляет все столбцы без изменений, кроме SP1
, который становится coalesce(sp1,sp2)
.
- использовать вид
view1
.
Как я уже сказал, огромный клочок и, пожалуйста, ради любви к любым богам, в которых вы верите, не используйте его. Но иногда нужно диктовать наши действия, поэтому я выкладываю это на всякий случай.
Все заботы, никакой ответственности, протестируйте (и профилируйте) это сами.
И, опубликовав это и обнаружив, что Дэмиен имеет более компактную версию, я также хотел бы предложить следующее.
Иногда полезно пожертвовать пространством ради времени (ускорить процесс за счет увеличения занимаемого места на диске).
Вы можете создать еще 8 столбцов, от MORPHSP1
до MORPHSP8
, для хранения измененных значений, которые я предложил в моем первом решении.
Это обычно нарушает 3NF, но на самом деле это нормально, если вы делаете две вещи: (1) понимаете последствия; и (2) уменьшить вероятность противоречивых данных.
Используя триггеры вставки / обновления, вы фактически можете гарантировать, что данные останутся непротиворечивыми.
При каждом изменении строки ваш триггер должен выполнять следующие действия.
set MORPHSP8 to coalesce (SP8,0)
set MORPHSP7 to coalesce (SP7,MORPHSP8)
set MORPHSP6 to coalesce (SP6,MORPHSP7)
set MORPHSP5 to coalesce (SP5,MORPHSP6)
set MORPHSP4 to coalesce (SP4,MORPHSP5)
set MORPHSP3 to coalesce (SP3,MORPHSP4)
set MORPHSP2 to coalesce (SP2,MORPHSP3)
set MORPHSP1 to coalesce (SP1,MORPHSP2)
Таким образом, вы несете расходы только при изменении данных, а не каждый раз, когда вы используете данные. В таблице, где число операций чтения превышает число записей (и это подавляющее большинство), это может привести к впечатляющему улучшению производительности.