Bonjour à tous !
Je viens vers vous car j'ai grand besoin d'un expert PHP ! Je m'explique :
Je dois migrer une base de données SQL Server 2005 vers SQL Server 2012 sur laquelle se connecte une petite application sous Symfony 1.4 (PHP 5.2.9-2).
Les drivers utilisés pour la connection était le php_mssql.dll.
Malheureusement, celui-ci n'est pas capable de se connecter à SQL Server 2012.
J'ai donc modifié le fichier database.yml et remplacé le driver mssql par le driver ODBC comme suit :
1 2 3 4 5 6 7
| all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: odbc:DRIVER={SQL Server};Server=VM2k12SQL12;Database=MaDatabase
username: sa
password: *********** |
Jusqu'ici tout va bien, mon application php se connecte bien à la base.
Mon problème est le suivant :
J'execute parfois des procédures stockées.
Celles-ci sont appelées de la façon suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| $bdd = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
//Donnée de la session
$p_tec_cod= $this->getRequestParameter('technicien');
$p_emp_cod = $nvvehicule; // <= issu d'un choix dans une combo box
$varsql = 'DECLARE @p_retour varchar(100);';
$execsql = 'EXEC p_liv_chg_vehicule ?,?,@p_retour OUTPUT;';
$selectsql = 'select @p_retour;';
$sql = $varsql.$execsql.$selectsql;
try
{
$stmt = $bdd->prepare($sql);
//Bind des paramètres en entrée
$stmt->bindParam(1, $p_tec_cod);
$stmt->bindParam(2, $p_emp_cod);
//Exécution
$stmt->execute();
//Bind des colonnes, récupération des paramètres en sortie
$stmt->bindColumn(1, $p_retour);
$row = $stmt->fetch(PDO::FETCH_BOUND);
}
catch (PDOException $e)
{
$p_retour= $e->getMessage();
} |
Malheureusement, à l'execution, j'obtiens l'erreur suivante :
SQLSTATE[24000]: Invalid cursor state: 0 [Microsoft][ODBC SQL Server Driver]État de curseur non valide (SQLFetchScroll[0] at ext\pdo_odbc\odbc_stmt.c:375)
Après investigation, en posant des traces SQL, je suis aperçu que la requete générée avait cette tête :
1 2 3 4 5 6
| declare @p1 int
set @p1=3
exec sp_prepare @p1 output,N'@P1 text,@P2 text',N'DECLARE @p_retour varchar(100);EXEC p_liv_chg_vehicule @P1,@P2,@p_retour OUTPUT;select @p_retour;',1
select @p1
EXEC sp_execute 3,'0000000119','VEHXPL004' |
Et c'est là qu'est le problème à mon avis : la préparation de la procédure stockée déclare deux variables @P1 et @P2 de type text, ce que SQL Server n'apprécie vraiment pas, d'autant que les paramètres d'entrée de ma procédure stockée sont de type VARCHAR(13) et VARCHAR(10) et le paramètre en OUTPUT est de type VARCHAR(100) (typiquement, ma procédure me renvoie "OK" ou "Erreur".
J'ai essayé de modifier la manière de d'affecter mes paramètres dans mon script php comme suit :
1 2
| $stmt->bindParam(1, $p_tec_cod, PDO::PARAM_STR,13);
$stmt->bindParam(2, $p_emp_cod? PDO::PARAM_STR,10); |
mais cela ne fonctionne pas non plus, ma trace affiche toujours @P1 et @P2 de type text...
je comprends bien que l'erreur qui s'affiche sur ma page signifie que le fetch s'est planté puisque la procédure n'a pas renvoyé de résultat, cependant j'ai pu vérifier qu'elle s'était bien executée...
En reprenant la requete générée et en modifiant le type text en varchar, je constate que cela marcherait correctement.
J'ai tenté de passer par la syntaxe suivante :
$stmt = $bdd->Query($sql);
en concaténant simplement les paramètres de ma procédure (je sais c'est moche !
), mais, autant je n'avais plus d'erreur, mais aucune valeur de retour non plus...
Ma question est donc la suivante :
- Avez-vous déjà rencontré ce problème de typage des paramètres de procédures stockées avec des drivers ODBC ?
- Auriez-vous une solution à me proposer ou une piste à me soumettre vers laquelle je pourrais me tourner ?
Merci d'avance à toute la communauté !
Raijin
Partager