php sql-server linux

php - El procedimiento almacenado no está devolviendo datos



sql-server linux (3)

Podría estar equivocado, pero creo que este es el comportamiento estándar de DBLIB y FreeTDS, ya que tienen una declaración por regla de conexión.

Para solucionar el objeto de conexión abierta para cada declaración, asegúrese de cerrar el cursor después de cada extracción.

$stmt->closeCursor();

sqlsrv en Windows no tiene este comportamiento, por lo tanto, los diferentes resultados en todas las plataformas.

Estoy en el proceso de transferir un script desde un servidor de Windows (descontinuado) a nuestro Linux. Uno de los scripts que necesito transferir es una conexión con un servidor MSSQL .

La conexión con el servidor está establecida y puedo obtener datos "regulares" de cualquiera de las tablas, pero cuando ejecuto un procedimiento almacenado, no recibo ninguno de los datos deseados. El procedimiento simplemente devuelve false cuando se ejecuta.

La prueba de errores en la declaración preparada con $stmt->errorInfo() no me muestra ninguna información relevante, simplemente devuelve el código de error 00000 , que debería indicar que todo (debería) funciona bien.

Array ( [0] => 00000 [1] => 0 [2] => (null) [0] (severity 0) [(null)] [3] => 0 [4] => 0 )

php

$con = new /PDO(''dblib:charset=UTF-8;host=freedts;dbname=database'', ''user'', ''password''); /** ------------------------------------------------------**/ $sql = ''SELECT * FROM prgroepen''; $stmt = $con->prepare($sql); if ($stmt) { try { $stmt->execute(); $data = $stmt->fetch(/PDO::FETCH_ASSOC); if ($data) echo ''<pre>''.print_r($data, true).''</pre>''; else var_dump($data); }catch(/Exception $e) { echo $e->getMessage(); } } /** ------------------------------------------------------**/ $SP = <<<SQL DECLARE @return_value int, @soort nvarchar(1), @dagen money EXEC @return_value = [dbo].[web_voorraadstatus] @produkt = N''ABEC24_9002'', @aantal = 1, @soort = @soort OUTPUT, @dagen = @dagen OUTPUT SELECT @soort as N''@soort'', @dagen as N''@dagen'' SQL; $stmt = $con->prepare($SP); if ($stmt) { try { $stmt->execute(); $data = $stmt->fetch(/PDO::FETCH_ASSOC); if ($data) echo ''<pre>''.print_r($data, true).''</pre>''; else var_dump($data); }catch(/Exception $e) { echo $e->getMessage(); } }

salida

Array ( [kode] => A [omschrijving] => ACCESSOIRE DISPLAYS [aeenheid] => ST [agb] => 604006 [veenheid] => ST [vgb] => 700011 [coefaank] => [coefverk] => [internet] => 1 [foto] => #//serverpc/fws$/GROEPEN/A.jpg# [vader] => [produkt_niveau] => 0 [bs_kode] => [bs_vader] => [web_volgorde] => 6 [pdfcataloog] => ) bool(false)

También intenté llamar al SP de diferentes maneras, pero sin ningún resultado. El mismo código exacto se ejecuta perfectamente en el servidor de Windows, con la única diferencia es que el servidor de Windows usa el sqlsrv sqlsrv

/** ============================== **/ /* @produkt as nvarchar(15), /* @aantal as money, /* @soort as nvarchar(1) output, /* @dagen as money output /** ============================== **/ $stmt = $con->prepare(''execute web_voorraadstatus ?, ?, ?, ?''); $stmt->bindParam(1, $produkt, PDO::PARAM_STR); $stmt->bindParam(2, $aantal, PDO::PARAM_STR); $stmt->bindParam(3, $soort, PDO::PARAM_STR, 1); $stmt->bindParam(4, $dagen, PDO::PARAM_STR, 10); var_dump($stmt->execute()); # true var_dump($soort, $dagen); # NULL, NULL

Entonces, ¿es dblib realmente capaz de ejecutar procedimientos almacenados y recuperar los datos que devuelve?

nota: el conjunto de caracteres del cliente ya está establecido en UTF-8 en el archivo de configuración FreeDTS

Aquí está un parcial del registro de freeDTS , parece que estoy recibiendo datos del servidor MSSQL está bien?

dblib.c:4639:dbsqlok(0x7fcfd8acc530) dblib.c:4669:dbsqlok() not done, calling tds_process_tokens() token.c:540:tds_process_tokens(0x7fcfd78d7bd0, 0x7ffe281bec38, 0x7ffe281bec3c, 0x6914) util.c:156:Changed query state from PENDING to READING net.c:555:Received header 0000 04 01 00 5c 00 37 01 00- |.../.7..| net.c:609:Received packet 0000 04 01 00 5c 00 37 01 00-79 00 00 00 00 fe 01 00 |.../.7.. y.......| 0010 e0 00 00 00 00 00 81 02-00 00 00 21 00 e7 02 00 |........ ...!....| 0020 09 04 d0 00 34 06 40 00-73 00 6f 00 6f 00 72 00 |....4.@. s.o.o.r.| 0030 74 00 00 00 21 00 6e 08-06 40 00 64 00 61 00 67 |t...!.n. [email protected]| 0040 00 65 00 6e 00 d1 02 00-56 00 08 00 00 00 00 90 |.e.n.... V.......| 0050 d0 03 00 fd 10 00 c1 00-01 00 00 00 |........ ....|


Si está limitado por la versión de PHP y FreeTDS, una especie de kludge podría servir en función de sus requisitos de rendimiento.

A grandes rasgos;

  1. Cree una vista basada en su procedimiento almacenado
  2. consultar la vista
  3. soltar la vista

Se discuten algunos enfoques diferentes en este hilo de MSDN: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/75a686f0-2192-4c6c-bdb8-04c074b916fc/create-view-from-stored-procedure?forum=transactsql

Notablemente:

declare @sql_String nvarchar(4000) set @sql_String = N'' create view dbo.Whatever as select ''''Hello World'''' as Hello_World'' exec sp_executeSql @sql_String


  • Intente ejecutar el Analizador de SQL en SQL Server y vea qué se está ejecutando y si está generando advertencias / errores.

  • ¿Podrías intentar ejecutar tu SP de la siguiente manera?

    SELECCIONAR CAST (soort AS NVARCHAR (1)) como N ''@ soort'', CAST (dagen AS MONEY) como N ''@ dagen''

    DESDE LA APERTURA ([nombre del servidor],

    DECLARAR @return_value int, @soort nvarchar (1), @dagen money

    EXEC @return_value = db_name. [Dbo]. [Web_voorraadstatus] @produkt = N''''ABEC24_9002 '''', @aantal = 1, @soort = @soort OUTPUT, @dagen = @dagen OUTPUT

    SELECCIONE @soort as N''''soort '''', @dagen as N''''dagen ''''

    '')

nombre_servidor es lo que se muestra en

select name from sys.servers where server_id = 0