Problème d'injection d'un paramètre VB dans une procédure stockée (FireBird)
-
19-08-2019 - |
Question
Tout le monde ici a toujours été d'une aide précieuse, directement ou indirectement. Et c’est avec un grand espoir que cela, encore une fois, sonne juste.
Par souci de clarté, la procédure stockée est exécutée sous FireBird et le VB appartient à la variété .NET
J'ai une procédure stockée (extrait ci-dessous, le bit important est WHERE)
select pn, pnm.description, si_number, entry_date, cmp_auto_key,
parts_flat_price, labor_flat_price, misc_flat_price, woo_auto_key,
wwt_auto_key
from parts_master pnm, wo_operation woo
where pn like :i_pn || '%'
and pnm.pnm_auto_key = woo.pnm_auto_key
into :pn, :description, :work_order, :entry_date, :cmp, :parts_price,
:labor_price, :misc_price, :woo, :wwt
J'essaie de transmettre un paramètre d'une application vb, qui utilise le paramètre I_PN, dont le code est indiqué ci-dessous (les variables pour MyServer et MyPassword sont déterminées dans une partie antérieure du code.)
Try
Dim FBConn As New FirebirdSql.Data.FirebirdClient.FbConnection()
Dim FBCmd As FirebirdSql.Data.FirebirdClient.FbCommand
Dim MyConnectionString As String
MyConnectionString = _
"datasource=" & MyServer & ";database=" & TextBox4.Text & "; & _
user id=SYSDBA;password=" & MyPassword & ";initial catalog=;"
FBConn = New FirebirdSql.Data.FirebirdClient. & _
FbConnection(MyConnectionString)
FBConn.Open()
FBConn.CreateCommand.CommandType = CommandType.StoredProcedure
FBCmd = New FirebirdSql.Data.FirebirdClient. & _
FbCommand("WIP_COSTS", FBConn)
FBCmd.CommandText = "WIP_COSTS"
FBConn.CreateCommand.Parameters. & _
Add("@I_PN", FirebirdSql.Data.FirebirdClient.FbDbType.Text). & _
Value = TextBox1.Text
Dim I_PN As Object = New Object()
Me.WIP_COSTSTableAdapter.Fill(Me.WOCostDataSet.WIP_COSTS, @I_PN)
FBConn.Close()
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
End Try
Lorsque j'exécute le fichier VB.App et que je tente d'exécuter le programme, l'erreur suivante apparaît:
Erreur SQL dynamique
Code d'erreur SQL = -206
Colonne inconnue
I_PN
À la ligne 1, colonne 29
Et je ne peux pas tout à fait mettre le doigt sur le problème réel. Cela signifie que je ne sais pas si ma logique est incorrecte du côté VB ou de la procédure stockée.
Tout codage inclus est associé à des exemples que j'ai trouvés avec divers bits de code trouvés au cours de longs séjours de GoogleFu.
Comme toute personne possédant plus d’un mois ou deux d’expérience (contrairement à moi) avec VB peut en attester d’un simple coup d’œil - mon code est probablement assez merdique et mal formé - et certainement pas élégant et opérationnel. Je suis certainement divertir tous les conseils de conseils à bras ouverts.
Comme d'habitude, si vous avez d'autres questions, j'y répondrai au mieux de mes capacités.
Merci encore.
Jasoomian
La solution
Après un peu de réflexion et un peu plus de recherche, j'ai enfin réussi à faire fonctionner mon code.
Try
' Code for checking server location and required credentials
Dim FBConn As FbConnection
' Dim FBAdapter As FbDataAdapter
Dim MyConnectionString As String
MyConnectionString = "datasource=" _
& MyServer & ";database=" _
& TextBox4.Text & ";user id=SYSDBA;password=" _
& MyPassword & ";initial catalog=;Charset=NONE"
FBConn = New FbConnection(MyConnectionString)
Dim FBCmd As New FbCommand("WIP_COSTS", FBConn)
FBCmd.CommandType = CommandType.StoredProcedure
FBCmd.Parameters.Add("@I_PN", FbDbType.VarChar, 40)
FBCmd.Parameters("@I_PN").Value = TextBox1.Text.ToUpper
Dim FBadapter As New FbDataAdapter(FBCmd)
Dim dsResult As New DataSet
FBadapter.Fill(dsResult)
Me.WIP_COSTSDataGridView.DataSource = dsResult.Tables(0)
Dim RecordCount As Integer
RecordCount = Me.WIP_COSTSDataGridView.RowCount
Label4.Text = RecordCount
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show _
("There was an error in generating the DataStream, " & _
"please check the system credentials and try again. " &_
"If the problem persists please contact your friendly " &_
"local IT department.")
End Try
' // end of line
J'avais également pensé que je devrais apporter des modifications à la procédure stockée réelle, mais cela s'est avéré incorrect.
Le code n'est peut-être pas beau et je dois travailler davantage dans mon bloc TRY pour une meilleure gestion des erreurs; mais ça marche.
Merci à tous ceux qui sont intervenus et m'ont aidé à rester sur la bonne voie.
Autres conseils
Essayez de changer ceci:
FBConn.CreateCommand.Parameters. & _
Add("@I_PN", FirebirdSql.Data.FirebirdClient.FbDbType.Text). & _
Value = TextBox1.Text
... à ceci:
FBCmd.Parameters.AddWithValue("@I_PN", TextBox1.Text)
En principe, vous souhaitez ajouter des paramètres de procédure stockée à l'objet Command, pas à l'objet Connection.
Andreik,
Voici l'intégralité de la procédure stockée. Et notre Firebird est la version 1.5.3, écrite avec IbExpert version 2006.12.13, Dialect 3
Begin
For
select pn, pnm.description, si_number, entry_date, cmp_auto_key, parts_flat_price,
labor_flat_price, misc_flat_price, woo_auto_key, wwt_auto_key
from parts_master pnm, wo_operation woo
where pn like :i_pn || '%'
and pnm.pnm_auto_key = woo.pnm_auto_key
into :pn, :description, :work_order, :entry_date, :cmp, :parts_price,
:labor_price, :misc_price, :woo, :wwt
Do begin
labor_hours = null;
work_type = null;
parts_cost = null;
labor_cost = null;
ro_cost = null;
customer = null;
select company_name
from companies
where cmp_auto_key = :cmp
into :customer;
select work_type
from wo_work_type
where wwt_auto_key = :wwt
into :work_type;
select sum(sti.qty*stm.unit_cost)
from stock_ti sti, stock stm, wo_bom wob
where sti.wob_auto_key = wob.wob_auto_key
and sti.stm_auto_key = stm.stm_auto_key
and wob.woo_auto_key = :woo
and sti.ti_type = 'I'
and wob.activity <> 'Work Order'
and wob.activity <> 'Repair'
into :parts_cost;
select sum(sti.qty*stm.unit_cost)
from stock_ti sti, stock stm, wo_bom wob
where sti.wob_auto_key = wob.wob_auto_key
and sti.stm_auto_key = stm.stm_auto_key
and wob.woo_auto_key = :woo
and sti.ti_type = 'I'
and wob.activity = 'Repair'
into :ro_cost;
select sum(wtl.hours*(wtl.fixed_overhead+wtl.variable_overhead+wtl.burden_rate)),
sum(wtl.hours)
from wo_task_labor wtl, wo_task wot
where wtl.wot_auto_key = wot.wot_auto_key
and wot.woo_auto_key = :woo
into :labor_cost, :labor_hours;
suspend;
end
End
Hardcode - J'ai répondu dans les commentaires à votre suggestion.