Cannot pass DateTime parameter to Stored Procedure - c#

I am struggling here with a very simple issue, but I have spent hours without progress.
I have this stored procedure:
PROCEDURE [Calculation_Upsert]
#Id INT = NULL,
#BillWho VARCHAR(50) = NULL,
#ClearingBroker VARCHAR(255) = NULL,
#Customer VARCHAR(255) = NULL,
#EffectiveDate DATETIME = NULL,
#ExecutingAccount VARCHAR(20) = NULL,
#ExecutingBroker VARCHAR(103) = NULL,
#Trader VARCHAR(255) = NULL,
#User VARCHAR(50)
AS...
Trying to execute it via EF6 dbContext, but I am getting strange errors. Most of the time the exception message is " ", sometimes "cannot convert 'nvarchar' to Datetime", and others the parameter #EffectiveDate is missing. I even tried to pass null, or DBNull.Value, or as string "2023-01-13T10:00:00" or "2023-01-13 10:00:00" and does not work.
var sqlparams = new object[]
{
new SqlParameter("#Id", Id),
new SqlParameter("#BillWho", BillWho),
new SqlParameter("#ClearingBroker",cb),
new SqlParameter("#Customer", cus),
new SqlParameter("#EffectiveDate", DBNull.Value), //tried also null, DateTime.UTCNow, "2023-01-13T10:00:00", "2023-01-13 10:00:00"
new SqlParameter("#ExecutingAccount", ea),
new SqlParameter("#ExecutingBroker", eb),
new SqlParameter("#Trader", trader),
new SqlParameter("#User",user)
};
try
{
//Method 1
return await _dbContext.Database.SqlQuery<int>("[Calculation_Upsert] #Id, #BillWho, #ClearingBroker, #Customer, #EffectiveDate, #ExecutingAccount, #ExecutingBroker, #Trader, #UserNbk",
sqlparams).ToListAsync();
This one returns "System.Data.SqlClient.SqlError: " and the exception message is " " when I am using DBNull.Value, or "Error convert nvarchar to DateTime" if I use DateTime.UTCNow or any string equivalent.
//Method 2
_dbContext.Calculation_Upsert(Id, BillWho, cb, cus, DateTime.UtcNow, ea, eb, trader, user);
return new List<int>() { 1 };
This returns "System.Data.Entity.Core.EntityCommandExecutionException: 'An error occurred while executing the command definition. See the inner exception for details.'" but the InnerException message is " ".
//Method 3
await _dbContext.Database.ExecuteSqlCommandAsync(
$"EXECUTE [Calculation_Upsert] #Id={Id}, #BillWho='{BillWho}', #ClearingBroker='{cb}', " +
$"#Customer='{cus}', #EffectiveDate='2023-01-13T14:08:00', #ExecutingAccount='{ea}', #ExecutingBroker='{eb}', #Trader='{trader}', #UserNbk='{user}'"
);
return new List<int>() { 1 };
}
This one returns "System.Data.SqlClient.SqlError: " and the exception message is " ".
I also tried to update the DB schema in my Edmx diagram, issue still persists.
This code, works fine into SQL Managment Tool:
DECLARE #return_value int
EXEC #return_value = [Calculation_Upsert]
#Id = 123,
#BillWho = 'Customer',
#ClearingBroker = 'Broker',
#Customer = 'My Customer',
#EffectiveDate = null, --'2023-01-13T14:08:00', **both values work**
#ExecutingAccount = '12345',
#ExecutingBroker = 'Eb',
#Trader = 'My Trader',
#User = 'username'
SELECT 'Return Value' = #return_value
GO
I am sure I am missing something small here, but cannot find what...

Related

Putting Null value to Not string column types

I want to know any ideas is available.
This images shows my table and Po_Settl column type is bit and Settled_ type is int.
So when user cancel the record I want to fill this again to the NULL value as shown as other rows.
As far this is done my manually, I press Ctrl+0 to change it to the null. So any other way to do this, Here with I will show my stored procedure that I wrote this to be work, but it's not working currently.
ALTER PROCEDURE [dbo].[Delete_PayBill]
#Req_Id int = NULL,
#Emp_Id varchar(10) = NULL,
#Reason varchar(50) = NULL,
#PO_Id int = NULL
AS
BEGIN
UPDATE [dbo].[App_Paybill]
SET [Cancelled_By] = #Emp_Id,
[Cancelled_Reason] = #Reason,
[Cancelled_Date] = GETDATE(),
[Status] = 0,
Po_SettleID = NULL
WHERE [Id] = #Req_Id
DECLARE #PayType VARCHAR(03)
SET #PayType= (SELECT [ReqType]
FROM [dbo].[Settleing_PaymentRequest]
WHERE [Payment_Id] = #Req_Id)
UPDATE Settleing_PaymentRequest
SET Status = 0
WHERE Payment_Id = #Req_Id
IF #PayType = 'PO'
BEGIN
UPDATE [dbo].[PO_Numbers]
SET [Po_Settled] = NULL, [Settled_By] = NULL
WHERE Req_Id = #PO_Id
END
ELSE IF #PayType = 'GR'
BEGIN
UPDATE App_Common_Request
SET Settled = NULL, SettlePendingStatus = NULL
WHERE Request_Id = #PO_Id
END
END

Error "Insufficient result space to convert uniqueidentifier value to char."

Table for the inserts:
CREATE TABLE [dbo].[CcureMessage]
(
[CcureMessageId] [UNIQUEIDENTIFIER] NOT NULL,
[Event] [VARCHAR](20) NULL,
[Type] [VARCHAR](20) NULL,
[Message] [VARCHAR](MAX) NOT NULL,
[Xml] [VARCHAR](4000) NOT NULL,
CONSTRAINT [PK_CcureMessage]
PRIMARY KEY CLUSTERED ([CcureMessageId] ASC)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[CcureMessage]
ADD CONSTRAINT [DF_CcureMessage_CcureMessageId]
DEFAULT (NEWID()) FOR [CcureMessageId]
GO
I made the PK table have a default value so that I'm not passing a GUID at all, yet it seems I'm still getting an error related to the guid.
Insert command that works fine through SSMS:
INSERT INTO CcureMessage (Event, Type, Message, Xml)
VALUES ('event 3', 'type 3', 'big json 3', 'xml-ish');
C# Code:
public void DoInsert(Message msg)
{
// hard-coding this to set test values
TopicMessage tm = new TopicMessage();
tm.Event = "event 1";
tm.Type = "Type 1";
tm.Message = "json data message";
tm.Xml = "xml data goes here";
string connString = set to correct value;
string sql = "INSERT INTO CcureMessage (Event, Type, Message, Xml) VALUES (#Event, #Type, #Message, #Xml)";
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = System.Data.CommandType.Text;
SqlParameter eventParm = new SqlParameter("#Event", tm.CcureMessageId);
SqlParameter typeParm = new SqlParameter("#Type", tm.Type);
SqlParameter msgParm = new SqlParameter("#Message", tm.Message);
SqlParameter xmlParm = new SqlParameter("#Xml", tm.Xml);
cmd.Parameters.Add(eventParm);
cmd.Parameters.Add(typeParm);
cmd.Parameters.Add(msgParm);
cmd.Parameters.Add(xmlParm);
cmd.ExecuteNonQuery();
}
}
Running this results in the error
Insufficient result space to convert uniqueidentifier value to char
The problem seems that you are passing guid to a varchar column in your code
SqlParameter eventParm = new SqlParameter("#Event", tm.CcureMessageId);
Should be:
SqlParameter eventParm = new SqlParameter("#Event", tm.Event);
In my case, I wasn't working with guids in the C# code and received this error. So tracing this back to the stored proc, I found that the error came directly from there.
I traced it down to a conversion I was running on a GUID field as follows:
CONVERT(varchar(13), guid)
I assumed it would simply truncate the field value. So I had to do the following:
CONVERT(varchar(13), CONVERT(varchar(36), guid))

Parameterized query that returns TEXT column(s) always returns zero for INT columns

Problemt with C# mySQL ODBC
My table
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fbid` varchar(30) NOT NULL,
`fbname` varchar(80) NOT NULL,
`datecreate` datetime NOT NULL,
`ipcreate` varchar(20) NOT NULL,
`datelogin` datetime NOT NULL,
`iplogin` varchar(20) NOT NULL,
`xstatus` int(2) NOT NULL,
`xverstion` int(5) NOT NULL,
`xdata` text NOT NULL,
`xitem` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
My procedure:
CREATE PROCEDURE `VVVVV_getUserByFbId`(fbid2 varchar(30))
BEGIN
SELECT * from vvvvv_account where vvvvv_account.fbid=fbid2 LIMIT 1;
END
fbid2 is parameter (=408301576730032)
in C# code
OdbcConnection connection = new OdbcConnection(constr);
OdbcCommand cmd;
DataTable dt = new DataTable();
try
{
OpenConnection(connection);
cmd = new OdbcCommand("{call VVVVV_getUserByFbId(?)}", connection);
cmd.Parameters.AddWithValue("#fbid2", "408301576730032");
cmd.CommandType = CommandType.StoredProcedure;
OdbcDataAdapter da = new OdbcDataAdapter(cmd);
da.Fill(dt);
da.Dispose();
}
catch (Exception ex)
{
}
finally
{
CloseConnection(connection);
}
return dt;
output in C#
dt.Rows[0]["id"] always = 0 Not Ok
dt.Rows[0]["fbname"] = "ABC" OK
means I can still get data from database normal. But int column alway = 0, varchar, datetime colume is ok;
But if I change the procedure to:
BEGIN
select * from account where account.fbid='408301576730032' LIMIT 1;
END
In C# "{call VVVVV_getUserByFbId()}" -> id field = 3903
If no parameter (fbid2) or no text fied (xdata, xitem) -> id, xstatus (int fields) return normal. But if an parameter is passed or select xdata -> id (int fields) always = 0;
enter image description here
You have encountered a verified bug in MySQL Connector/ODBC, reported here:
https://bugs.mysql.com/bug.php?id=97191
Since you are using C# you may want to see if MySQL Connector/NET works better for your application.
Please try to convert the returning value to int as follows.
int x = System.Convert.ToInt32(dt.Rows[0]["id"]);
The issue might be that MySql int is not mapping to C# int.

Entity Framework issue with varchar out parameter Error converting data type varchar to int

I having an issue with out parameter that is return #SecurityGroup varchar(100) value is 'admin', this is the only out parameter that throws an error from sp, the other are working. The error is
Error converting data type varchar to int
Why would it try to convert a varchar to int?
ALTER PROCEDURE [LDR].[usp_UI_GetUserProfile]
#User VARCHAR(50),
#MatchTypeID INT,
#SecurityGroup VARCHAR(100) OUTPUT,
#NumofRowsAllowed INT OUTPUT,
#ReturnStatus INT OUTPUT,
#ReturnErrorMessage NVARCHAR(4000) OUTPUT
Entity Framework call
var parameters = new[] {
new SqlParameter("#User", UserID){Direction = System.Data.ParameterDirection.Input},
new SqlParameter("#MatchTypeID", MatchTypeID){Direction = System.Data.ParameterDirection.Input},
new SqlParameter("#SecurityGroup", DbType.String){Direction = System.Data.ParameterDirection.Output},
new SqlParameter("#NumofRowsAllowed", DbType.Int32){Direction = System.Data.ParameterDirection.Output},
new SqlParameter("#ReturnStatus", DbType.Int32){Direction = System.Data.ParameterDirection.Output},
new SqlParameter("#ReturnErrorMessage", DbType.String){Direction = System.Data.ParameterDirection.Output}
};
var results = db.Database.ExecuteSqlCommand("exec [LDR].[usp_UI_GetUserProfile] #UserNetID, #MatchTypeID, #SecurityGroup out, #NumofRowsAllowed out, #ReturnStatus out, #ReturnErrorMessage out", parameters[0], parameters[1], parameters[2], parameters[3], parameters[4], parameters[5]);
It might be a simple thing to wrap it in a try catch block and throw a breakpoint on the catch statement. If you do that you can see what VS is trying to do that is so wrong

An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll but was not handled in user code

Error I get:
An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll but was not handled in user code
Additional information: Invalid object name sp_VehicleInfo.
Code:
protected void btnRegister_Click(object sender, EventArgs e)
{
VehicleInfo vehicle = new VehicleInfo();
vehicle.VehicleNo = txtVehicleNo.Text;
vehicle.Make = txtMake.Text;
vehicle.Model = txtEmail.Text;
vehicle.Variety = txtVersion.Text;
//vehicle.isAc = radAC.Text;
vehicle.EngineNo = TextBox1.Text;
vehicle.LExpDate = txtLicenseExpDate.Text;
vehicle.InsuranceNo = TextBox2.Text;
vehicle.IExpDate = txtInsuranceExpDate.Text;
vehicle.Insert();
}
and this is the stored procedure
[dbo].[sp_VehicleInfo]
#VehicleNo NVARCHAR(50) = NULL,
#Make NVARCHAR(50) = NULL,
#Model NVARCHAR(50) = NULL,
#Variety NVARCHAR(50) = NULL,
#isAc BIT = NULL,
#EngineNo NVARCHAR(50) = NULL,
#LExpDate NVARCHAR(50) = NULL,
#InsuranceNo NVARCHAR(50) = NULL,
#IExpDate NVARCHAR(50) = NULL,
#VehicleId bigint = NULL,
#mode NVARCHAR(50)
AS
BEGIN
IF(#mode = 'insert')
BEGIN
INSERT INTO sp_VehicleInfo (VehicleNo, Make, Model, Variety, isAc, EngineNo, LExpDate, InsuranceNo, IExpDate)
OUTPUT inserted.VehicleNo
VALUES (#VehicleNo, #Make, #Model, #Variety, #isAc, #EngineNo, #LExpDate, #InsuranceNo, #IExpDate)
END
IF(#mode = 'update')
BEGIN
UPDATE sp_VehicleInfo
SET VehicleNo = Isnull(#VehicleNo, VehicleNo),
Make = Isnull(#Make, Make),
Model = Isnull(#Model, Model),
Variety = Isnull(#Variety, Variety),
isAc = Isnull(#isAc, isAc),
EngineNo = Isnull(#EngineNo, EngineNo),
LExpDate = Isnull(#LExpDate, LExpDate),
InsuranceNo = Isnull(#InsuranceNo, InsuranceNo),
IExpDate = Isnull(#IExpDate, IExpDate)
WHERE
VehicleId = #VehicleId
END
IF(#mode = 'get' )
BEGIN
SELECT *
FROM sp_VehicleInfo
WHERE VehicleId = #VehicleId
END
IF(#mode = 'delete')
BEGIN
DELETE FROM sp_VehicleInfo
WHERE VehicleId = #VehicleId
END
END
This is a common error message. You are trying to access sp_VehicleInfo somewhere in your code and it seems like it is not a valid object in your database. From the naming convention you followed, I suppose it is a stored procedure. Check your database if this object is available or not.
Please note the following:
It may not be a good way to start a database object's name with "sp_" as system stored procedures follows that naming convention.
Please include all the code relevant to your question like the code that accesses the database in the post

Categories