簡體   English   中英

sql中引用的參數是拋出的out參數異常

[英]Parameter referenced in sql is an out parameter exception thrown

我有一個命名的原始即席查詢,並使用輸出參數執行。 我相信我將輸入和輸出參數都正確地添加到命令對象中。 我試圖了解Npgsql中輸出參數的解析過程及其失敗的原因。 任何想法..我試圖在這里提供一些信息。.讓我知道您是否可以幫助或需要其他信息。 我認為這應該是一個簡單的用例,用於插入一些數據並使用out參數從命名查詢中獲取一些標量返回值

Postgres

BEGIN

 SELECT nextval('Role_seq') into :v_roleId;

  INSERT INTO Role (roleId, organizationId, name, notes, locked, roleTypeId, rightsFlags)
  VALUES (:v_roleId, :v_organizationId, :v_name, :v_notes, :v_locked, :v_roleTypeId, :v_rightsFlags);

END;

SQL服務器

    INSERT INTO Role (organizationId, name, notes, locked, roleTypeId, rightsFlags)
VALUES (@organizationId, @name, @notes, @locked, @roleTypeId, @rightsFlags)
SELECT @roleId = SCOPE_IDENTITY()

甲骨文

BEGIN
  SELECT Role_roleId_SEQ.NEXTVAL into :v_roleId FROM DUAL;

  INSERT INTO Role (roleId, organizationId, name, notes, locked, roleTypeId, rightsFlags)
  VALUES (:v_roleId, :v_organizationId, :v_name, :v_notes, :v_locked, :v_roleTypeId, :v_rightsFlags);
END;

我正確綁定了所有參數,並且此代碼可在除某些查詢解析失敗的Postgres之外的所有平台(提供者)上運行。 這是我添加參數的方式。

   dsh.AddNQParameter(cmd, "roleId", ParameterDirection.Output, (object)DBNull.Value, "Int", "Int32", "Integer");
            dsh.AddNQParameter(cmd, "organizationId", ParameterDirection.Input, organizationId ?? (object)DBNull.Value, "Int", "Int32", "Integer");
            dsh.AddNQParameter(cmd, "name", ParameterDirection.Input, name ?? (object)DBNull.Value, "VarChar", "Varchar2", "Varchar");
            dsh.AddNQParameter(cmd, "notes", ParameterDirection.Input, notes ?? (object)DBNull.Value, "VarChar", "Varchar2", "Varchar");
            dsh.AddNQParameter(cmd, "locked", ParameterDirection.Input, locked ?? (object)DBNull.Value, "Bit", "Byte", "Boolean");
            dsh.AddNQParameter(cmd, "roleTypeId", ParameterDirection.Input, roleTypeId ?? (object)DBNull.Value, "Int", "Int32", "Integer");
            dsh.AddNQParameter(cmd, "rightsFlags", ParameterDirection.Input, rightsFlags ?? (object)DBNull.Value, "Image", "Blob", "Bytea");

Postgres的堆棧跟蹤

Result StackTrace:  
at Npgsql.SqlQueryParser.ParseRawQuery(String sql, Boolean standardConformantStrings, NpgsqlParameterCollection parameters, List`1 statements)
   at Npgsql.NpgsqlCommand.ProcessRawQuery()
   at Npgsql.NpgsqlCommand.<Execute>d__71.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.NpgsqlCommand.<ExecuteNonQuery>d__84.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Npgsql.NpgsqlCommand.ExecuteNonQuery()
   at LandisGyr.Data.Helper.ExecuteNonQueryReturnInt(DbCommand cmd, String name) in D:\tfs\cc\Command Center\Components\LGDALGenerator\Main\LG.Data.Core\Foundation\Helper.cs:line 76
   at DAL_Generator_Test.Data.NamedQueries.Test.NamedQueriesTest.InsRole(DbCommand cmd, Nullable`1 organizationId, String name, String notes, Nullable`1 locked, Nullable`1 roleTypeId, Byte[] rightsFlags, Nullable`1& roleId) in D:\tfs\cc\Command Center\Components\LGDALGenerator\Main\DAL Generator Test\Data\NamedQueries\NamedQueries.Test.Designer.cs:line 985
   at DAL_Generator_Test.SqlServerTests.NamedQueriesPostgresTests.Execute_NonQuery_Test_Using_DbCommand() in D:\tfs\cc\Command Center\Components\LGDALGenerator\Main\DAL Generator Test\PostgresTests\NamedQueriesPostgresTests.cs:line 90
Result Message: 
Test method DAL_Generator_Test.SqlServerTests.NamedQueriesPostgresTests.Execute_NonQuery_Test_Using_DbCommand threw exception: 
System.Exception: Parameter ':v_roleId' referenced in SQL but is an out-only parameter

代碼示例來再現問題

using Npgsql;
using NpgsqlTypes;
using System;
using System.Configuration;
using System.Data.Common;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectString = ConfigurationManager.ConnectionStrings["PostgresTest"].ConnectionString;

            // create a table as follows
            /*
             * CREATE TABLE  role
(
    roleid integer NOT NULL DEFAULT nextval('role_seq'::regclass),
    name character varying(50) COLLATE pg_catalog."default",
    notes character varying(255) COLLATE pg_catalog."default",
    organizationid integer NOT NULL,
    roletypeid integer NOT NULL DEFAULT 0,
    locked boolean NOT NULL DEFAULT false,
    rightsflags bytea
)
             */
            using (NpgsqlConnection con = new NpgsqlConnection(connectString))
            {

                con.Open();

                using (DbCommand cmd = con.CreateCommand())
                {
                    cmd.CommandText = @"BEGIN

 SELECT nextval('Role_seq') into: v_roleId;

                    INSERT INTO Role(roleId, organizationId, name, notes, locked, roleTypeId, rightsFlags)
  VALUES(:v_roleId, :v_organizationId, :v_name, :v_notes, :v_locked, :v_roleTypeId, :v_rightsFlags);

                    END;";

                    var roleIdParam = new NpgsqlParameter(":v_roleId", NpgsqlDbType.Integer);
                    roleIdParam.Direction = System.Data.ParameterDirection.Output;
                    cmd.Parameters.Add(roleIdParam);

                    var orgParam = new NpgsqlParameter(":v_organizationId", NpgsqlDbType.Integer);
                    orgParam.Direction = System.Data.ParameterDirection.Input;
                    orgParam.Value = 1;
                    cmd.Parameters.Add(orgParam);

                    var nameParam = new NpgsqlParameter(":v_name", NpgsqlDbType.Varchar);
                    nameParam.Direction = System.Data.ParameterDirection.Input;
                    nameParam.Value = "test role";
                    cmd.Parameters.Add(nameParam);

                    var lockedParam = new NpgsqlParameter(":v_locked", NpgsqlDbType.Boolean);
                    lockedParam.Direction = System.Data.ParameterDirection.Input;
                    lockedParam.Value = false;
                    cmd.Parameters.Add(lockedParam);


                    var roleTypeIdParam = new NpgsqlParameter(":v_roleTypeId", NpgsqlDbType.Integer);
                    roleTypeIdParam.Direction = System.Data.ParameterDirection.Input;
                    roleTypeIdParam.Value = 1;
                    cmd.Parameters.Add(roleTypeIdParam);


                    var rightsFlagsParam = new NpgsqlParameter(":v_rightsFlags", NpgsqlDbType.Bytea);
                    rightsFlagsParam.Direction = System.Data.ParameterDirection.Input;
                    rightsFlagsParam.Value = DBNull.Value;
                    cmd.Parameters.Add(rightsFlagsParam);


                    cmd.ExecuteNonQuery();


                    object roleId = cmd.Parameters[":v_roleId"].Value;

                    Console.WriteLine($"role id is {roleId}");

                    Console.WriteLine("Press any key to continue");

                    Console.ReadLine();

                }
            }

        }
    }
}

我已經閱讀了有關“輸入/輸出參數”的文檔。 https://www.npgsql.org/doc/basic-usage.html

在非常相似的情況下,我進行了一個測試,返回了序列的值。

請注意,您未在SQL語句中設置輸出參數。 INSERT INTO x RETURNING x.roleId :roleId

樣例代碼

using Npgsql;
using NpgsqlTypes;
using System;
using System.Configuration;
using System.Data.Common;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectString = ConfigurationManager.ConnectionStrings["PostgresTest"].ConnectionString;

            using (NpgsqlConnection con = new NpgsqlConnection(connectString))
            {

                con.Open();

                using (DbCommand cmd = con.CreateCommand())
                {
                    cmd.CommandText = @"INSERT INTO Role(roleId, organizationId, name, notes, locked, roleTypeId, rightsFlags)
  VALUES(nextval('Role_seq'), :v_organizationId, :v_name, :v_notes, :v_locked, :v_roleTypeId, :v_rightsFlags) RETURNING roleId";

                    var orgParam = new NpgsqlParameter(":v_organizationId", NpgsqlDbType.Integer);
                    orgParam.Direction = System.Data.ParameterDirection.Input;
                    orgParam.Value = 1;
                    cmd.Parameters.Add(orgParam);

                    var nameParam = new NpgsqlParameter(":v_name", NpgsqlDbType.Varchar);
                    nameParam.Direction = System.Data.ParameterDirection.Input;
                    nameParam.Value = "test role";
                    cmd.Parameters.Add(nameParam);

                    var lockedParam = new NpgsqlParameter(":v_locked", NpgsqlDbType.Boolean);
                    lockedParam.Direction = System.Data.ParameterDirection.Input;
                    lockedParam.Value = false;
                    cmd.Parameters.Add(lockedParam);


                    var roleTypeIdParam = new NpgsqlParameter(":v_roleTypeId", NpgsqlDbType.Integer);
                    roleTypeIdParam.Direction = System.Data.ParameterDirection.Input;
                    roleTypeIdParam.Value = 1;
                    cmd.Parameters.Add(roleTypeIdParam);


                    var rightsFlagsParam = new NpgsqlParameter(":v_rightsFlags", NpgsqlDbType.Bytea);
                    rightsFlagsParam.Direction = System.Data.ParameterDirection.Input;
                    rightsFlagsParam.Value = DBNull.Value;
                    cmd.Parameters.Add(rightsFlagsParam);


                    var roleIdParam = new NpgsqlParameter("Returning_roleIdParam", NpgsqlDbType.Integer);
                    roleIdParam.Direction = System.Data.ParameterDirection.Output;
                    cmd.Parameters.Add(roleIdParam);

                    cmd.ExecuteNonQuery();


                    object roleId = cmd.Parameters["Returning_roleIdParam"].Value;

                    Console.WriteLine($"role id is {roleId}");

                    Console.WriteLine("Press any key to continue");

                    Console.ReadLine();

                }
            }

        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM