Tengo un procedimiento almacenado que devuelve 80 columnas y 300 filas. Quiero escribir una selección que obtenga 2 de esas columnas. Algo como
SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'
Cuando utilicé la sintaxis anterior obtengo el error:
"Nombre de columna inválido".
Sé que la solución más fácil sería cambiar el procedimiento almacenado, pero no lo escribí y no puedo cambiarlo.
¿Hay alguna forma de hacer lo que quiero?
Podría hacer una tabla temporal para poner los resultados, pero debido a que hay 80 columnas, necesitaría hacer una tabla temporal de 80 columnas solo para obtener 2 columnas. Quería evitar rastrear todas las columnas que se devuelven.
Intenté usar
WITH SprocResults AS ....
como lo sugirió Mark, pero obtuve 2 erroresSintaxis incorrecta cerca de la palabra clave 'EXEC'.
Sintaxis incorrecta cerca ')'.Intenté declarar una variable de tabla y recibí el siguiente error
Error de inserción: el nombre de la columna o el número de valores proporcionados no coincide con la definición de la tabla
Si lo intento
SELECT * FROM EXEC MyStoredProc 'param1', 'param2'
me sale el error:Sintaxis incorrecta cerca de la palabra clave 'exec'.
fuente
EXEC
no es una palabra clave MySQL (el equivalente de MySQL es declaraciones preparadas ). Aunque me gustaría saber la respuesta para MySQL, las respuestas a continuación apuntan a T-SQL. ReetiquetadoRespuestas:
¿Puedes dividir la consulta? Inserte los resultados de proceso almacenados en una variable de tabla o una tabla temporal. Luego, seleccione las 2 columnas de la variable de tabla.
fuente
Aquí hay un enlace a un documento bastante bueno que explica todas las diferentes formas de resolver su problema (aunque muchas de ellas no se pueden usar ya que no puede modificar el procedimiento almacenado existente).
Cómo compartir datos entre procedimientos almacenados
La respuesta de Gulzar funcionará (está documentada en el enlace de arriba) pero será una molestia escribirla (necesitará especificar los 80 nombres de columna en su declaración @tablevar (col1, ...). Y en el futuro Si se agrega una columna al esquema o se cambia la salida, deberá actualizarse en su código o se producirá un error.
fuente
Fuente:
http://stevesmithblog.com/blog/select-from-a-stored-procedure/
fuente
Esto funciona para mí: (es decir, solo necesito 2 columnas de las más de 30 devueltas por
sp_help_job
)Antes de que esto funcionara, necesitaba ejecutar esto:
.... para actualizar la
sys.servers
tabla. (es decir, el uso de una autorreferencia dentro de OPENQUERY parece estar deshabilitado de forma predeterminada).Por mi simple requisito, no encontré ninguno de los problemas descritos en la sección OPENQUERY del excelente enlace de Lance.
Rossini, si necesita establecer dinámicamente esos parámetros de entrada, el uso de OPENQUERY se vuelve un poco más complicado:
No estoy seguro de las diferencias (si las hay) entre usar
sp_serveroption
para actualizar lasys.servers
autorreferencia existente directamente, versus usarsp_addlinkedserver
(como se describe en el enlace de Lance) para crear un duplicado / alias.Nota 1: Prefiero OPENQUERY sobre OPENROWSET, dado que OPENQUERY no requiere la definición de la cadena de conexión dentro del proceso.
Nota 2: Habiendo dicho todo esto: normalmente solo usaría INSERT ... EXEC :) Sí, son 10 minutos más de tipeo, pero si puedo evitarlo, prefiero no moverme con:
(a) comillas dentro de comillas dentro de citas, y
(b) tablas del sistema y / o configuraciones de servidor vinculado autorreferenciadas y escurridizas (es decir, para esto, necesito defender mi caso ante nuestros poderosos DBA :)
Sin embargo, en este caso, no pude usar una construcción INSERT ... EXEC, como
sp_help_job
ya estoy usando una. ("No se puede anidar una instrucción INSERT EXEC").fuente
Para lograr esto, primero debe crear un me
#test_table
gusta a continuación:Ahora ejecute el procedimiento y ponga valor en
#test_table
:Ahora obtiene el valor de
#test_table
:fuente
Si puede modificar su procedimiento almacenado, puede poner fácilmente las definiciones de columnas necesarias como parámetro y utilizar una tabla temporal creada automáticamente:
En este caso, no necesita crear una tabla temporal manualmente, se crea automáticamente. Espero que esto ayude.
fuente
Puede ser útil saber por qué esto es tan difícil. Un procedimiento almacenado solo puede devolver texto (imprimir 'texto'), o puede devolver varias tablas, o puede no devolver ninguna tabla.
Entonces algo como
SELECT * FROM (exec sp_tables) Table1
no funcionaráfuente
(Suponiendo SQL Server)
La única forma de trabajar con los resultados de un procedimiento almacenado en T-SQL es usar la
INSERT INTO ... EXEC
sintaxis. Eso le da la opción de insertar en una tabla temporal o una variable de tabla y desde allí seleccionar los datos que necesita.fuente
Un truco rápido sería agregar un nuevo parámetro
'@Column_Name'
y hacer que la función de llamada defina el nombre de la columna que se va a recuperar. En la parte de devolución de su sproc, tendría sentencias if / else y devolvería solo la columna especificada, o si está vacío, devuelva todo.fuente
Si está haciendo esto para la validación manual de los datos, puede hacerlo con LINQPad.
Cree una conexión a la base de datos en LinqPad y luego cree declaraciones C # similares a las siguientes:
Referencia http://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx
fuente
Para SQL Server, encuentro que esto funciona bien:
Cree una tabla temporal (o una tabla permanente, en realidad no importa) y realice una inserción en la declaración con el procedimiento almacenado. El conjunto de resultados del SP debe coincidir con las columnas de su tabla, de lo contrario obtendrá un error.
Aquí hay un ejemplo:
¡Eso es!
fuente
Como se mencionó en la pregunta, es difícil definir la tabla temporal de 80 columnas antes de ejecutar el procedimiento almacenado.
Por lo tanto, al revés, debe completar la tabla en función del conjunto de resultados del procedimiento almacenado.
Si recibe algún error, debe habilitar consultas distribuidas ad hoc ejecutando la siguiente consulta.
Para ejecutar
sp_configure
con ambos parámetros para cambiar una opción de configuración o para ejecutar laRECONFIGURE
instrucción, se le debe otorgar elALTER SETTINGS
permiso de nivel de servidorAhora puede seleccionar sus columnas específicas de la tabla generada
fuente
prueba esto
fuente
Sé que ejecutar desde sp e insertar en la tabla temporal o variable de tabla sería una opción, pero no creo que sea su requisito. Según su requisito, esta declaración de consulta a continuación debería funcionar:
si tiene conexión de confianza, use esta declaración de consulta a continuación:
si obtiene un error al ejecutar la declaración anterior, simplemente ejecute esta declaración a continuación:
Espero que esto ayude a alguien que haya enfrentado este tipo de problema similar. Si alguien intentara con una tabla temporal o variable de tabla que debería ser así a continuación, pero en este escenario debe saber cuántas columnas está devolviendo su sp, entonces debe crear esa cantidad de columnas en la tabla temporal o variable de tabla:
fuente
Para cualquiera que tenga SQL 2012 o posterior, pude lograr esto con procedimientos almacenados que no son dinámicos y tienen la misma salida de columnas cada vez.
La idea general es que construyo la consulta dinámica para crear, insertar, seleccionar y soltar la tabla temporal, y ejecutar esto después de que todo se haya generado. Genero dinámicamente la tabla temporal recuperando primero los nombres y tipos de columna del procedimiento almacenado .
Nota: existen soluciones mucho mejores y más universales que funcionarán con menos líneas de código si desea / puede actualizar el SP o cambiar la configuración y el uso
OPENROWSET
. Use el siguiente si no tiene otra manera.fuente
La forma más fácil de hacerlo si solo necesita hacer esto una vez:
Exportar a Excel en el asistente Importar y Exportar y luego importar este Excel a una tabla.
fuente
Cree una vista dinámica y obtenga resultados de ella .......
fuente
Cortaría y pegaría el SP original y eliminaría todas las columnas excepto las 2 que desee. O. Traería el resultado establecido, lo mapearía a un objeto comercial apropiado, luego LINQ fuera de las dos columnas.
fuente