2010-10-01 22 views
271

Tengo una consulta SELECT compleja, desde la que me gustaría insertar todas las filas en una variable de tabla, pero T-SQL no lo permite.SELECCIONAR EN una variable de tabla en T-SQL

En la misma línea, no puede usar una variable de tabla con las consultas SELECT INTO o INSERT EXEC. http://odetocode.com/Articles/365.aspx

ejemplo corto:

declare @userData TABLE(
         name varchar(30) NOT NULL, 
         oldlocation varchar(30) NOT NULL 
         ) 

SELECT name, location 
INTO @userData 
FROM myTable 
    INNER JOIN otherTable ON ... 
WHERE age > 30 

Los datos de la variable de tabla se utilizó posteriormente para insertar/actualizar de nuevo en tablas diferentes (en su mayoría copia de los mismos datos con actualizaciones menores). El objetivo de esto sería simplemente hacer que el guión sea un poco más legible y más fácil de personalizar que haciendo el SELECT INTO directamente en las tablas correctas. El rendimiento no es un problema, ya que el rowcount es bastante pequeño y solo se ejecuta manualmente cuando es necesario.
... o solo dime si lo estoy haciendo todo mal.

Respuesta

423

intentar algo como esto:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL, 
    oldlocation varchar(30) NOT NULL 
); 

INSERT INTO @userData (name, oldlocation) 
SELECT name, location FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age > 30; 
+0

Si selecciona "nombre, ubicación FROM myTable" como los valores que va a insertar en la tabla UserData, no importa si los nombres de las variables en la selección coinciden con los nombres en la definición de la tabla. Está seleccionando 'nombre' para ir a la variable 'nombre' UserData, pero está seleccionando 'ubicación' y de alguna manera asignándola a la variable UserData 'oldlocation'. ¿SQL solo asignará estos automáticamente o arrojará algún tipo de excepción? –

+0

No importa el nombre, solo el tipo de columna. – CristiC

+3

Wow, eso tiene sentido, pero al mismo tiempo el analizador en mí se siente un poco ofendido :) –

6

Intente utilizar INSERT en lugar de SELECT INTO:

INSERT @UserData 
SELECT name, location etc. 
12

Usted podría tratar de usar tablas temporales ...

SELECT name, location INTO #userData FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age>30 

omite el esfuerzo para declarar la mesa de esa manera ... Ayuda para consultas adhoc ... Esto crea una tabla temporal local que no será visible para otras conexiones a menos que use la misma conexión en su aplicación.

si necesita las variables que puede ser declarado de esta manera:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL, 
    oldlocation varchar(30) NOT NULL 
); 

INSERT INTO @userData 
SELECT name, location FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age > 30; 
+2

Lo sentimos, se olvidó de mencionar que no tengo derechos para CREATE TABLE. – Indrek

+6

Crear una temperatura tiene un poco más de sobrecarga. – Paparazzi

+2

usando tabla temporal no siempre es seguro. Por ejemplo, servicios web.Con servicios web con una sola conexión para limitar la conexión máxima en el servidor Y proteger el SQL de SQL un poco más, la tabla temporal existirá para TODAS las consultas que pasen y puede sobrescribir a alguien que la esté usando actualmente. – Franck

77

El propósito de SELECT INTO es (por la documentación, el énfasis es mío)

Para crear una nueva tabla de valores en otra tabla

Pero usted ya tiene a target table! Así que lo que quiere es

La declaración INSERT añade una o más nuevas filas a una tabla

Puede especificar los valores de datos en los siguientes maneras:

...

Mediante el uso de una subconsulta SELECT para especificar los valores de datos para una o más filas, tales como:

INSERT INTO MyTable 
(PriKey, Description) 
     SELECT ForeignKey, Description 
     FROM SomeView 

Y en esta sintaxis, se permitió MyTable a ser una variable de tabla .

+0

¡Gracias por la explicación! – Indrek

+0

¡Realmente desearía que la respuesta aceptada incluyera esta información! –

+0

obtengo MyTable es "Nombre de Objeto Inválido" haciendo esto, por lo que falta algo en esta respuesta. –

-4

Una razón para utilizar SELECT INTO es que le permite utilizar IDENTIDAD:

SELECT IDENTITY(INT,1,1) AS Id, name 
INTO #MyTable 
FROM (SELECT name FROM AnotherTable) AS t 

Esto no funcionaría con una variable de tabla, que es demasiado malo ...

+5

Sin embargo, puede declarar una variable de tabla con una columna 'IDENTITY'. –

4

En primer lugar crear una temp tabla:

Paso 1:

create table #tblOm_Temp (

    Name varchar(100), 
    Age Int , 
    RollNumber bigint 
) 

** Paso 2: ** Inserte algún valor en la tabla Temp.

insert into #tblom_temp values('Om Pandey',102,1347) 

Paso 3: declara una variable tabla para guardar datos de la tabla temp.

declare @tblOm_Variable table(

    Name Varchar(100), 
    Age int, 
    RollNumber bigint 
) 

Paso 4: valor de selección de tabla temporal e inserte en la variable tabla.

insert into @tblOm_Variable select * from #tblom_temp 

Por último valor se inserta desde una tabla temporal a la tabla de variables

Paso 5: puede comprobar valor insertado en la variable de tabla.

select * from @tblOm_Variable 
13

También puede usar expresiones de tabla comunes para almacenar conjuntos de datos temporales. Son más elegante y amigable adhoc:

WITH userData (name, oldlocation) 
AS 
(
    SELECT name, location 
    FROM myTable INNER JOIN 
     otherTable ON ... 
    WHERE age>30 
) 
SELECT * 
FROM userData -- you can also reuse the recordset in subqueries and joins 
+0

Me encanta esto! Gracias. – fourpastmidnight

0

OK, ahora con el suficiente esfuerzo soy capaz de insertar en @table mediante el siguiente:

INSERT SELECT @TempWithheldTable
a.SuspendedReason, a.SuspendedNotes, a.SuspendedBy, a.ReasonCode FROM OPENROWSET (BULK 'C: \ bases \ WithHeld.csv', FORMATFILE = N'C: \ bases \ Format.txt',
ErrorFile = N'C : \ Te mp \ MovieLensRatings.txt ' ) AS a;

Lo principal aquí es seleccionar columnas para insertar.

Cuestiones relacionadas