Параметр, на который ссылается sql, является исключением параметра out
У меня есть именованный необработанный специальный запрос и выполняется с выходным параметром. Я добавляю и входные и выходные параметры к объекту команды должным образом, я верю. Я пытаюсь понять, что синтаксический анализ, который продолжается для выходных параметров в Npgsql и почему это не удается. Любые идеи.. Я попытался предоставить некоторую информацию здесь.. Дайте мне знать, если вы можете помочь или нужна дополнительная информация. Я думаю, что это должен быть простой вариант использования для вставки некоторых данных и получения скалярных возвращаемых значений из именованного запроса с использованием параметров
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 Server
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();
}
}
}
}
}
0 ответов
Я прочитал документацию по "Параметры входа / выхода". https://www.npgsql.org/doc/basic-usage.html
Я сделал тест, который возвратил значение последовательности, в очень похожем случае.
Обратите внимание, что вы не устанавливаете выходной параметр в операторе SQL. INSERT INTO x RETURNING x.roleId
INTO: 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();
}
}
}
}
}