由于代码中的切换行,存储过程切换参数

时间:2018-06-23 17:01:11

标签: c# sql firebird

我有一个看起来像这样的存储过程(不要读它,因为80%与该问题无关,因此请先阅读其余部分):

COMMIT WORK;
SET AUTODDL OFF;
SET TERM ^ ;

/* Stored procedures */

CREATE PROCEDURE "NAPRAVISTAVKU" 
(
  "VRDOK" SMALLINT,
  "BRDOK" INTEGER,
  "ROBAID" INTEGER,
  "CENA_BEZ_PDV" NUMERIC(15, 2),
  "KOL" NUMERIC(15, 3),
  "RABAT" NUMERIC(15, 2)
)
RETURNS
(
  "OK" SMALLINT
)
AS
BEGIN EXIT; END ^


ALTER PROCEDURE "NAPRAVISTAVKU" 
(
  "VRDOK" SMALLINT,
  "BRDOK" INTEGER,
  "ROBAID" INTEGER,
  "CENA_BEZ_PDV" NUMERIC(15, 2),
  "KOL" NUMERIC(15, 3),
  "RABAT" NUMERIC(15, 2)
)
RETURNS
(
  "OK" SMALLINT
)
AS
DECLARE VARIABLE MAGACINID SMALLINT;
DECLARE VARIABLE MTID VARCHAR(10);
DECLARE VARIABLE NAZIV VARCHAR(50);
DECLARE VARIABLE TARIFAID VARCHAR(3);
DECLARE VARIABLE NABAVNACENA NUMERIC(15, 4);
DECLARE VARIABLE POREZ NUMERIC(15, 2);
BEGIN
  OK = 0;

  SELECT MAGACINID, MTID FROM DOKUMENT
  WHERE VRDOK = :VRDOK AND BRDOK = :BRDOK
  INTO :MAGACINID, :MTID;

  SELECT NAZIV FROM ROBA WHERE ROBAID = :ROBAID
  INTO :NAZIV;

  SELECT NABAVNACENA FROM ROBAUMAGACINU
  WHERE MAGACINID = :MAGACINID AND ROBAID = :ROBAID
  INTO :NABAVNACENA;

  IF (CENA_BEZ_PDV = 0) THEN BEGIN
    SELECT PRODAJNACENA FROM ROBAUMAGACINU
    WHERE MAGACINID = :MAGACINID AND ROBAID = :ROBAID
    INTO :CENA_BEZ_PDV;
  END

  SELECT TARIFAID FROM ROBA WHERE ROBAID = :ROBAID
  INTO TARIFAID;

  SELECT STOPA FROM TARIFE WHERE TARIFAID = :TARIFAID
  INTO :POREZ;

  INSERT INTO STAVKA (VRDOK, BRDOK, MAGACINID, ROBAID, VRSTA, NAZIV, NABCENSAPOR, FAKTURNACENA, NABCENABT,
              TROSKOVI, NABAVNACENA, PRODCENABP, KOREKCIJA, PRODAJNACENA, DEVIZNACENA, DEVPRODCENA, KOLICINA,
              NIVKOL, TARIFAID, IMAPOREZ, POREZ, RABAT, MARZA, TAKSA, AKCIZA, PROSNAB, PRECENA, PRENAB, PROSPROD,
              MTID, PT, TREN_STANJE, POREZ_ULAZ, DEVNABCENA, POREZ_IZ)
  VALUES (:VRDOK, :BRDOK, :MAGACINID, :ROBAID, 1, :NAZIV, 0, 0, 0, 
           0, :NABAVNACENA, :CENA_BEZ_PDV, 0, :CENA_BEZ_PDV, 0, 0, :KOL,
           0, :TARIFAID, 0, :POREZ, :RABAT, 0, 0, 0, 0, 0, 0, 0, 
           :MTID, 'P', 0, 0, 0, :POREZ);

  SUSPEND;

  /* Obrada greske */
  WHEN ANY DO
  BEGIN
    OK = -1;
    SUSPEND;
  END

END
 ^

SET TERM ; ^
COMMIT WORK;
SET AUTODDL ON;

在我的C#代码中,我像这样执行它:

using (FbConnection con = new FbConnection(M.Baza.connectionKomercijalno2018))
{
    con.Open();

    using (FbCommand cmd = new FbCommand("NAPRAVISTAVKU", con))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("VRDOK", vrDok);
        cmd.Parameters.AddWithValue("BRDOK", brDok);
        cmd.Parameters.AddWithValue("ROBAID", robaId);
        cmd.Parameters.AddWithValue("CENA_BEZ_PDV", (cenaBezPDV == null) ? 0 : cenaBezPDV);
        cmd.Parameters.AddWithValue("KOL", kolicina);
        cmd.Parameters.AddWithValue("RABAT", (rabat == null) ? 0 : rabat);
        cmd.Parameters.Add("OK", FbDbType.SmallInt).Direction = ParameterDirection.Output;

        cmd.ExecuteScalar();

        int a = Convert.ToInt32(cmd.Parameters["OK"].Value);
        return Convert.ToBoolean(cmd.Parameters["OK"].Value);
    }
}

(我解决的问题)是由于某种原因,表中的两列被切换了(我都在传递):CENA_BEZ_PDVKOL

我已经打了大约3个小时的头,以找出问题所在。我多次使用 rubber ducking ,找不到逻辑上的解释为什么它不起作用,然后在我里面变笨了,尝试切换2行。

所以在切换两行之前,我的代码如下:

cmd.Parameters.AddWithValue("ROBAID", robaId);
cmd.Parameters.AddWithValue("KOL", kolicina);
cmd.Parameters.AddWithValue("CENA_BEZ_PDV", (cenaBezPDV == null) ? 0 : cenaBezPDV);**
cmd.Parameters.AddWithValue("RABAT", (rabat == null) ? 0 : rabat);

然后我切换了两行,分别用逻辑传递KOLCENA_BEZ_PDV,让我们像在存储过程中一样使它排序,并使其正常工作。

请问我为什么会这样?完全相同的代码只是交换了几行,因此它符合存储过程中的顺序,并且可以正常工作。

甚至这个命名参数是否意味着任何东西或代码只是按过程参数的顺序添加了参数?

也许这不是Firebird或SQL问题,而是c#?

0 个答案:

没有答案