Как изменить ячейку таблицы в зависимости от ее типа столбца? - PullRequest
0 голосов
/ 25 июня 2019

Я хочу обновить ячейки в таблице SQL в зависимости от типа ее столбца. Более конкретно, я хочу заменить значения NULL либо на «», либо на 0,0,0, либо на «1900-01-01» в зависимости от типа столбца. В таблице 60 столбцов, поэтому ручной подход неудобен.

Подход, который я попробовал, использует метаданные, и я хочу сгенерировать скрипт обновления.

Вариант использования предназначен для импорта в Excel, где значения NULL должны быть обработаны в зависимости от типа столбца.

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Как уже говорилось в комментариях, проще всего использовать ''. Единственное исключение (я обнаружил) было для decimal / numeric, где неявное и явное преобразование не допускается.

Как показано ниже, вы можете записать утверждение (но я исключаю столбец decimal) или сделать это динамически:

USE Sandbox;
GO

CREATE TABLE TestTable (ID int IDENTITY(1,1),
                        SomeInt int,
                        SomeDecimal decimal(10,2),
                        SomeFloat float,
                        SomeMoney money,
                        SomeDate date,
                        SomeDatetime datetime,
                        SomeTime time,
                        SomeDatetime2 datetime2(1),
                        SomeVarbinary varbinary(12),
                        SomeVarchar varchar(10),
                        SomeBit bit);
INSERT INTO dbo.TestTable (SomeInt,
                           SomeDecimal,
                           SomeFloat,
                           SomeMoney,
                           SomeDate,
                           SomeDatetime,
                           SomeTime,
                           SomeDatetime2,
                           SomeVarbinary,
                           SomeVarchar,
                           SomeBit)
VALUES(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
      (NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
GO
UPDATE dbo.TestTable
SET SomeInt = ISNULL(SomeInt,''),
    --SomeDecimal = ISNULL(SomeDecimal,''),
    SomeFloat = ISNULL(SomeFloat,''),
    SomeMoney = ISNULL(SomeMoney,''),
    SomeDate = ISNULL(SomeDate,''),
    SomeDatetime = ISNULL(SomeDatetime,''),
    SomeTime = ISNULL(SomeTime,''),
    SomeDatetime2 = ISNULL(SomeDatetime2,''),
    SomeVarbinary = ISNULL(SomeVarbinary,CONVERT(varbinary,'')),
    SomeVarchar = ISNULL(SomeVarchar,''),
    SomeBit = ISNULL(SomeBit,'')
WHERE ID = 1;
GO
DECLARE @Schema sysname = N'dbo',
        @Table sysname = N'TestTable';

DECLARE @SQL nvarchar(MAX);

SET @SQL = N'UPDATE ' + QUOTENAME(@Schema) + N'.' + QUOTENAME(@Table) + NCHAR(13) + NCHAR(10) +
           N'SET ' + STUFF((SELECT N',' + NCHAR(13) + NCHAR(10) + 
                                   N'    ' + QUOTENAME(C.COLUMN_NAME) + N' = ISNULL(' + QUOTENAME(C.COLUMN_NAME) + N',' + CASE C.DATA_TYPE WHEN N'decimal' THEN '0)'
                                                                                                                                           WHEN N'numeric' THEN '0)'
                                                                                                                                           ELSE N'CONVERT(' + QUOTENAME(C.DATA_TYPE) + N',N''''))'
                                                                                 END
                            FROM INFORMATION_SCHEMA.COLUMNS C
                            WHERE C.TABLE_SCHEMA = @Schema
                              AND C.TABLE_NAME = @Table
                              AND C.COLUMN_NAME != 'ID' --You'll need a better method to ignore your ID column
                            FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,7,N'') + NCHAR(13) + NCHAR(10) +
          N'WHERE ID = 2;'; --you won't want this if you're doing every row.

PRINT @SQL;

EXEC sp_executesql @SQL;
GO
SELECT *
FROM dbo.TestTable;

GO
DROP TABLE dbo.TestTable

дб <> скрипка

Если вы используете SQL Server 2017+, вы можете упростить вышесказанное, используя STRING_AGG вместо FOR XML PATH и STUFF для создания списка столбцов в таблице с разделителями.

0 голосов
/ 25 июня 2019
SELECT COLUMN_NAME AS colname, DATA_TYPE AS coltype
INTO #result_columns
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'mytable';


WITH cte(colname, default_value) AS (

SELECT colname,

    CASE
        WHEN coltype IN ('varchar','nvarchar') THEN ''''''
        WHEN coltype IN ('int','money') THEN '0'
        WHEN coltype IN ('date') THEN '''1900-01-01'''
        WHEN coltype IN ('float') THEN '0.0'
    END AS default_value
FROM #result_columns

) 
SELECT 'UPDATE mytable SET ' + colname + '=' + default_value + ' WHERE ' + colname + ' IS NULL;' 

FROM cte;

- результат:

UPDATE mytable SET Caracteristique='' WHERE Caracteristique IS NULL;
UPDATE mytable SET Couleur='' WHERE Couleur IS NULL;
UPDATE mytable SET Forme='' WHERE Forme IS NULL;
UPDATE mytable SET Machine='' WHERE Machine IS NULL;
UPDATE mytable SET QteChargee=0.0 WHERE QteChargee IS NULL;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...