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;
- Cree una vista basada en su procedimiento almacenado
- consultar la vista
- 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