2011-03-28 30 views
27

Cuando creo una tabla temporal usando un select into en SQL Server, ¿hay alguna manera de especificar que una columna debe ser anulable? Tengo un proceso de varios pasos en el que estoy creando una tabla temporal seleccionando muchas columnas (por lo que no estoy haciendo un create table #tmp (...)). Después de hacer esa tabla temporal, estoy actualizando algunas columnas y algunas de esas actualizaciones pueden anular un campo.Crear una columna que se pueda nulos mediante SQL Server SELECT INTO?

Sé que podría hacer una declaración alter table alter column para lograr lo que quiero, pero tengo curiosidad acerca de si hay una forma de especificar esto en el select. Sé que puede alinear sus columnas en cast para obtener el tipo de datos deseado, pero no veo cómo especifica la capacidad de anulación.

Respuesta

22

Nulability se hereda de la columna fuente.

Puede perder o ganar nulabilidad con una expresión:

Ejemplo (literales constantes parecen ser problemático - necesita una buena función NOOP que puede devolver NULL):

CREATE TABLE SO5465245_IN 
    (
    a INT NOT NULL 
    ,b INT NULL 
    ) ; 
GO 

SELECT COALESCE(a, NULL) AS a 
     ,ISNULL(b, 0) AS b 
     ,COALESCE(10, NULL) AS c1 
     ,COALESCE(ABS(10), NULL) AS c2 
     ,CASE WHEN COALESCE(10, NULL) IS NOT NULL THEN COALESCE(10, NULL) ELSE NULL END AS c3 
INTO SO5465245_OUT 
FROM SO5465245_IN ; 
GO 

SELECT TABLE_NAME 
     ,COLUMN_NAME 
     ,IS_NULLABLE 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME LIKE 'SO5465245%' 
ORDER BY TABLE_NAME 
     ,ORDINAL_POSITION ; 
GO 

DROP TABLE SO5465245_IN ; 
GO 

DROP TABLE SO5465245_OUT ; 
GO 
+0

'NULLIF' parece funcionar muy bien cuando se utiliza una columna. Tu respuesta me hizo pensar en probar 'COALESCE (col_name, null)' que funciona universalmente sin necesidad de inventar un valor imposible. Sin embargo, hay una situación en la que ninguna parece funcionar, y es cuando selecciona un literal como 'select nullif ('asdf', '~') como Value en _Test'. NULLIF/COALESCE parece que es lo suficientemente bueno, pero ¿hay alguna otra manera que funcione en todas las situaciones? – mattmc3

+0

@ mattmc3 - algunos operadores eluden eso (por ejemplo, ABS funciona en el ejemplo anterior), pero NULLIF no es suficiente. –

0

Recientemente tuve la misma problema: quería utilizar "seleccionar en", quería que todas las columnas de la tabla de destino fueran nulables & un enfoque repetible en el que no tuviera que conocer los nombres de los campos en la tabla fuente.

select * 
into dbo.I_Data 
from 
    (select 1[Z_1]) A 
    full join (select null[Z_2], * from dbo.S_Data) B on A.Z_1 = B.Z_2 

donde dbo.S_Data es la tabla de datos de origen y [Z_ 1] & [Z _2] son ​​dos columnas ficticias usadas para la combinación

Luego de limpiar:

(a) Eliminar la fila de valores nulos

delete dbo.I_Data where [Z_1] = 1 

(b) Retirar la fie maniquí lds:

alter table dbo.I_Data 
    drop column [Z_1], [Z_2] 

Saludos.

10

Este Soulution He llegado recientemente con ya pesar de que debería compartir:

select top 0 
    B.* 
into 
    TargetTable 
from 
    SourceTable as A 
    left join SourceTable as B on 1 = 0 

Esto crea una estructura duplicada de SourceTable en TargetTable con todas las columnas anulables (al menos en SQL2008).

1

Si desea heredar nullablity para la columna de destino, independientemente de las columnas de la tabla fuente, puede seguir esta consulta.

SELECT COLUMN1, COLUMN2, COLUMN3 INTO DestinationTable from SourceTable 

si esto era su consulta en la COLUMN1, COLUMN2, COLUMN3 no fuera anulable en SourceTable a continuación, cambiar la consulta como

SELECT NULL COLUMN1, NULL COLUMN2, NULL COLUMN3 INTO DestinationTable from SourceTable 

es así, esto le permitirá insertar valores nulos en la tabla de destino .

+0

El lado negativo de esto es que debe soltar el registro vacío – UnhandledExcepSean

+0

¿Qué registro vacío? – Kilokahn

+0

En SQL Server, esto hace que la columna sea de tipo int, lo que no es deseable. – Kilokahn

1

Esto también funciona.

select * 
into #so20150909 
from table 
where 1=0 
2

CONVERT hará que sus columnas sean nulables, y también funciona para literales/constantes. Probado en SQL Server 2005/2008.

SELECT 
    SomeText = CONVERT(varchar(10), 'literal'), 
    SomeNumber = CONVERT(int, 0) 
INTO SO5465245 

INSERT SO5465245 VALUES (null, null) 

SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, IS_NULLABLE 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'SO5465245' 
ORDER BY TABLE_NAME, ORDINAL_POSITION 

DROP TABLE SO5465245 
Cuestiones relacionadas