Ejecute el procedimiento almacenado de DB2 iSeries desde un servidor vinculado de SQL 2005
-
11-07-2019 - |
Pregunta
Estoy tratando de ejecutar un procedimiento almacenado desde una base de datos vinculada en MS SQL 2005. La base de datos vinculada es una base de datos db2 en un servidor iseries. Estoy usando el proveedor de servicios iSeries IBMDASQL. Puedo consultar el procedimiento almacenado sin problemas usando un simple vbscript y ado. Cuando intento ejecutar el mismo procedimiento almacenado en el analizador de consultas en SQL Server, nunca veo ningún resultado. El analizador de consultas siempre muestra 'comando ejecutado' y cuando ejecuto select * en la tabla temporal, no aparecen valores. ¿¿¿¿¿Qué estoy haciendo mal????? Gracias!
--código del analizador de consultas a continuación--
DECLARE @emailToAddress char(50)
DECLARE @emailFromAddress char(50)
set @emailToAddress = 'customer.service@company.com'
set @emailFromAddress = 'customer@gmail.com'
If Object_ID('tempdb..#tmpResultTbl') Is Not Null
Drop Table #tmpResultTbl
Create Table #tmpResultTbl
(
OUTPGMID Char(150))
--SET FMTONLY Off
Set NoCount On
Insert Into #tmpResultTbl
EXEC ('CALL abicqual.VP_GETCCEPGMID(?, ?) ', @emailToAddress, @emailFromAddress) AT MAM400
Select * From #tmpResultTbl
ACTUALIZADO: Aquí está el código actualizado para usar openquery ... todavía no hay suerte :(
DECLARAR @TSQL varchar (8000) DECLARE @emailToAddress varchar (50) DECLARE @emailFromAddress varchar (50) SET @emailToAddress = 'customer.service@company.com' SET @emailFromAddress = 'customer@gmail.com' SET @TSQL = 'SELECT * FROM OPENQUERY (MAM400,' 'CALL abicqual.VP_GETCCEPGMID (' '' '' + @emailToAddress + '' '' ',' '' '' + @emailFromAddress + '' '' '' + ')' '' + ')' Imprimir @TSQL EXEC (@TSQL)
--salida a continuación-- SELECCIONAR * DE OPENQUERY (MAM400, 'CALL abicqual.VP_GETCCEPGMID (' 'customer.service@company.com' ',' 'customer@gmail.com' ')') Mensaje 7357, Nivel 16, Estado 2, Línea 1 No se puede procesar el objeto " CALL abicqual.VP_GETCCEPGMID ('customer.service@company.com ',' customer@gmail.com ') " ;. El proveedor OLE DB " IBMDASQL " para el servidor vinculado "MAM400" indica que el objeto no tiene columnas o que el usuario actual no tiene permisos sobre ese objeto.
Solución
Resulta que hay una serie de problemas con el proveedor IBMDASQL que estaba usando. Lo creas o no, es más rápido y más confiable usar el proveedor Microsoft OLE DB para los controladores ODBC. Después de crear un nuevo servidor vinculado con este proveedor, todos mis intentos de sql anteriores funcionaron correctamente. ¡Saludos!
Otros consejos
Estoy usando el proveedor Microsoft DB2OLEDB que está disponible como parte del Feature Pack para SQL 2005 - abril de 2006. También es parte de Host Integration Services. Se conecta al AS / 400 utilizando el protocolo DRDA (estilo Oracle).
Puede descargarlo por separado, pero solo se instalará en SQL estándar, empresarial o desarrollador (no express).
También encuentro que compilando la consulta completa que quiero ejecutar en el cuadro DB2 / 400 y luego envolviéndola en una cadena VARCHAR (MAX) que también incluye el " SELECT * FROM OPENQUERY (--linkedservername--, --DB2 / 400 consulta con params -) " y luego usar los comandos sp_execute o EXEC devuelve los mejores resultados.
Incluso es posible envolver el código RPG dentro de los procedimientos SQL de DB2 / 400 y luego llamarlos (con parámetros) desde el servidor MS SQL y devolver cualquier conjunto de resultados como una tabla MS SQL.
Intente usar OPENQUERY . Esta publicación de blog muestra un ejemplo de paso de variables a una instrucción OPENQUERY.
llame al procedimiento oracle (función) a través del servidor vinculado y obtenga su resultado (valor de retorno)
--input parameters p1, p2, p3 declare @SQL nvarchar(1000) declare @param nvarchar(100) declare @result varchar(20) -- numbers may cause data type error -- (...custom actions, i.e. insert to local table) set @SQL = N'set @result = (select * from openquery(myLinkedServer, ''select OwnerName.Function_Insert(' + cast(@p1 as varchar) + ', ' + cast(@p1 as varchar) + ', ' + cast(@p3 as varchar) + ') from dual''))' set @param = '@result varchar output' EXEC sp_executesql @SQL, @param, @result output if @result '0' goto ERROR -- (...custom actions) return 1 -- OK ERROR: -- (...custom actions, i.e. delete from local table with(rowlock)) return 0 -- KO
La solución es agregar corchetes alrededor de la declaración de llamada. Sin embargo, aún no podrá seleccionar en una tabla al final de SQL Server a menos que haya instalado soporte para transacciones distribuidas. No estoy seguro de por qué necesita una transacción, pero no funcionará a menos que tenga esto configurado.
EXEC ('{CALL abicqual.VP_GETCCEPGMID (?,?)}', @emailToAddress, @emailFromAddress) EN MAM400