I'm executing a SQL Server stored procedure which returns a single output parameter using AsyncPoco:
CREATE PROCEDURE [dbo].[GenerateId]
(#RETVAL VARCHAR(12) OUTPUT)
AS
DECLARE #pkgID VARCHAR(12)
BEGIN
SELECT #pkgID = 'ABC' + '000'
SELECT #RETVAL = #pkgID
END
GO
Here's how I'm calling it:
var spOutput = new SqlParameter("#RETVAL", System.Data.SqlDbType.VarChar)
{
Direction = System.Data.ParameterDirection.Output,
Size = 12,
};
var sql = $";EXEC [dbo].[GenerateId] #0 OUTPUT";
var response = await _dbAdapter.FetchAsync<dynamic>(sql, new object[] { spOutput });
return (string)spOutput.Value;
This is the error I get:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Object.GetType()
at AsyncPoco.Database.FormatCommand(String sql, Object[] args) in C:\Aldenteware\AsyncPoco\code\AsyncPoco\Database.cs:line 2279
I figured it out:
var spOutput = new SqlParameter("#RETVAL", System.Data.SqlDbType.VarChar)
{
Direction = System.Data.ParameterDirection.Output,
Size = 12,
};
var sql = $";EXEC [dbo].[GenerateId] ##RETVAL = #0 OUTPUT";
var sqlClass = new Sql();
var s = sqlClass.Append(sql, spOutput);
var response = await _dbAdapter.ExecuteAsync(s);
return (string)spOutput.Value;
Related
How can i call OUT parameter in PROCEDURE via Npgsql
I am getting this error when i run below code
-- PostgreSQL 14 -> PROCEDURE
CREATE OR REPLACE PROCEDURE sp_add_users_new(arrJsnUsers JSON[], jOut OUT JSON) AS $$
DECLARE
intSpStatus INT;
v json;
BEGIN
FOREACH v IN ARRAY arrJsnUsers
LOOP
INSERT INTO tbl_user (vhr_name, vhr_password, sin_record_status)
VALUES(v->>'strName', v->>'strPassword', (v->>'intRecordStatus')::SMALLINT);
END LOOP;
COMMIT;
intSpStatus = 1;
jOut['intSpStatus'] = intSpStatus;
END;
$$ LANGUAGE plpgsql
--Dot net core 5
using (NpgsqlConnection objCon = new NpgsqlConnection("..."))
{
objCon.Open();
using (NpgsqlCommand objSqlCommand = new NpgsqlCommand("CALL sp_add_users_new(:p1, :p2)", objCon))
{
// Parameters
NpgsqlParameter[] lstSqlParameter = {
new NpgsqlParameter("p1", NpgsqlDbType.Array|NpgsqlDbType.Json) {
Value = lstUsers,
DataTypeName = "arrJsnUsers"
},
new NpgsqlParameter("p2", NpgsqlDbType.Json) {
Value = jOut,
DataTypeName = "jOut",
Direction = ParameterDirection.Output
},
};
objSqlCommand.Parameters.AddRange(lstSqlParameter);
// Execute
IDataReader objDataReader = objSqlCommand.ExecuteReader();
}
objCon.Close();
}
--Error
42703: column "p2" does not exist
Below is a sample which works - it's recommended to read the Npgsql docs on this. Some comments:
You don't specify the output parameter in SQL - just pass a NULL as per the PostgreSQL docs.
Since #p2 is an output parameter, it makes no sense to specify its value (jOut1 above).
DataTypeName (jOut above) also doesn't make sense here; that's used to indicate to Npgsql which PG type to send for input parameters (similar to NpgsqlDbType).
using var objCon = new NpgsqlConnection("Host=localhost;Username=test;Password=test");
objCon.Open();
using var objSqlCommand = new NpgsqlCommand("CALL sp_add_users_new(#p1, NULL)", objCon);
// Parameters
var lstUsers = new[] { #"{ ""Foo"": ""Bar"" }" };
NpgsqlParameter[] lstSqlParameter = {
new NpgsqlParameter("p1", NpgsqlDbType.Array|NpgsqlDbType.Json) { Value = lstUsers, DataTypeName = "arrJsnUsers"},
new NpgsqlParameter("p2", NpgsqlDbType.Json) { Direction = ParameterDirection.Output},
};
objSqlCommand.Parameters.AddRange(lstSqlParameter);
// Execute
IDataReader objDataReader = objSqlCommand.ExecuteReader();
Console.WriteLine(objSqlCommand.Parameters[1].Value);
I have created an API called GetCustomerPrivacyStatus, it is trying to find out the TandCstatus.
[HttpGet]
[Route("GetCustomerPrivacyStatus")]
public async Task<EULAInfo> GetCustomerPrivacyStatus()
{
var result = new EULAInfo();
string userObjectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var orgId = await GetOrgIdOfUser().ConfigureAwait(false);
var TandCvalue = MasterDatabase.GetTermsAndConditionstatus(orgId).ToString();
var TandCInt = TandCvalue != null ? TandCvalue : "0";
var TandCstatus = Int16.Parse(TandCInt) == 0 ? false : true;
result.status = TandCstatus;
return result;
}
In the GetTermsAndConditionstatus it is calling a stored procedure, if the orgId is new that means it is not present is the database, that's why dataTable.Rows[0]["TermsAndConditionAccepted"] is throwing an error
There is no row at position 0
I am not able to able to think how to resolve this situation.
public object GetTermsAndConditionstatus(string orgId)
{
using (var reader = new StoredProcedureReader(this, "GetTermsAndConditionstatus", new { orgId }))
{
var dataTable = reader.ReadDataTable();
var result = dataTable.Rows[0]["TermsAndConditionAccepted"] ;
return result;
}
}
Stored procedure is:
CREATE PROCEDURE [dbo].[GetTermsAndConditionstatus]
#orgId VARCHAR(100)
AS
SELECT TermsAndConditionAccepted
FROM TermsAndConditionCheck
WHERE OrgId = #orgId
Is there is any way if there is no rows the result variable should be set to null?
object result = null;
using (var reader = new StoredProcedureReader(this, "GetTermsAndConditionstatus", new { orgId }))
{
var dataTable = reader.ReadDataTable();
if (dataTable.Rows.Count > 0)
result = dataTable.Rows[0]["TermsAndConditionAccepted"];
}
return result;
That should fix your problem
I try to count line in my SQL query.
It works without parameter. For example, if I assign directly FIOForm = 'SmithJJ'. I really don't understand what I'm doing wrong.
Exception: the SqlParameter is already contained by another SqlParameterCollection
int kolNar = 0;
System.Data.SqlClient.SqlParameter Name = new System.Data.SqlClient.SqlParameter("#Name", System.Environment.UserName);
var pushStat = db.Database.SqlQuery<Reestr>("select * from Reestr where FIOForm = #Name and Status = 'Executed'", Name);
foreach (var u in pushStat)
{
kolNar = pushStat.Count();
}
if (kolNar > 0)
MessageBox.Show(kolNar.ToString());
I suppose you can call:
Dispose();
before
System.Data.SqlClient.SqlParameter Name = new System.Data.SqlClient.SqlParameter("#Name", System.Environment.UserName);
I want return all records when data.Task = 0 in this query. how to do it?
var data = SqlConn.ConnectSQL().Query("Select TicketNo, PickName From TaxiTicket Where DriverID = #ID AND Status = #State",
new { ID = find.Account, State = data.Task });
var data = SqlConn.ConnectSQL().Query("Select TicketNo, PickName From TaxiTicket
Where DriverID = #ID AND (Status = case #State when 0 then Status else #state end)",
new { ID = find.Account, State = data.Task });
this only addresses your point of question, how you prepare and pass parameters is another issue. you seem to have some weird assignment using same data variable.
I have a query using Npgsql and Postgres. For building my query I am using Dapper and its SqlBuilder.
When I make the normal statement in the DB it is returning the correct result. When I am doing it via the SqlBuilder it is returning the wrong result.
I tried different way, changed the addTemplate or the parameters, but it changed nothing.
Also I have tried to change the line builder.Where("period = #period", new { model.Period }); in different ways:
builder.Where("period = #Period", new { model.Period });
builder.Where("period = period", new { model.Period });
builder.Where("period = #TestPeriod", new { TestPeriod = model.Period });
Or is this a more common way:
builder.Where("period = '" + model.Period + "'");
using (NpgsqlConnection con = Helper.GetNpgsqlConnection())
{
var builder = new SqlBuilder();
var selector = builder.AddTemplate("SELECT * FROM szzRecord.folders /**where**/");
if (model.Period != null)
builder.Where("period = #period", new { model.Period });
var result = con.Query(selector.RawSql);
return result;
}
The result with the normal sql query for example: SELECT * FROM szzRecord.folders WHERE period = 24 is returning 251 rows - which is correct.
The result with the dapper query is 1223, which are all rows. So it kinda looks that the parameter doesn't exist. On expecting the selector I find my parameter for period. I found Period = 24 inselector.parameters.templates[0]. Is this correct? selector.parameters.parameters is empty.
You need to pass the SqlBuilder's parameters into your query. You have:
var result = con.Query(selector.RawSql);
Change this to:
var result = con.Query(selector.RawSql, selector.Parameters);