Getting only first character in Output parameter in C# - c#

I have defined output parameter as shown below:
C#:
scom.Parameters.Add("#User_ID",SqlDbType.VarChar,8).Direction = ParameterDirection.Output ;
Sql:
#User_ID varchar(8) output
I am getting complete string when executing procedure in Sql Server, but getting only first character in C#. I searched a lot and ensured that size is defined in both C# and Sql. Even I tried with fixed length character (Char(8)), but still getting only first character in C#. Please let me know what is the issue.
C# Code:
public bool CheckPhone(string phoneNumber)
{
SqlConnection myconn=new SqlConnection(connectionString);
try
{
myconn.Open();
SqlCommand scom = new SqlCommand("AuthenticatePhone", myconn);
scom.CommandType = CommandType.StoredProcedure;
scom.Parameters.Add("#phoneNumber", SqlDbType.BigInt).Value = Convert.ToInt64(phoneNumber);
scom.Parameters.Add("#User_ID", SqlDbType.Char, 8).Direction = ParameterDirection.Output;
scom.Parameters.Add("#User_Name", SqlDbType.Char, 120).Direction = ParameterDirection.Output;
scom.ExecuteNonQuery();
if (scom.Parameters["#User_Name"] == null)
{
return false;
}
else
{
UserID = (string)scom.Parameters["#User_ID"].Value;//.ToString();
UserName = (string)scom.Parameters["#User_Name"].Value;//.ToString();
myconn.Close();
return true;
}
}
catch (Exception e)
{
string error = e.InnerException + e.Message;
}
finally
{
myconn.Close();
}
return false;
}
Sql:
Create procedure dbo.AuthenticatePhone
#phoneNumber numeric(11,0) ,
#User_ID varchar(8) output ,
#User_Name varchar(120) output
as
begin
Select #User_ID = convert(varchar(8),[User_ID]) ,
#User_Name = [User_Name]
from dbo.NRE_Users
where PhoneNumber = #phoneNumber
;
print #User_ID
print #User_Name
end

Try to use the below code:
Parameter[param number].Size = 200;

Doesn't repro for me. Given this stored procedure:
create procedure dbo.AuthenticatePhone
#phoneNumber numeric(11,0) ,
#User_ID varchar(8) output ,
#User_Name varchar(120) output
as
set #User_ID = '1234567890' -- should be truncated to '12345678'
set #User_Name = 'The quick brown fox jumped over the lazy dog.'
return 0
go
Running this SQL in SSMS:
declare #userId varchar(1000) = 'xxx'
declare #userName varchar(1000) = 'yyy'
exec AuthenticatePhone 1 , #User_ID = #userId out , #User_Name = #userName out
select #userId,#userName
results in the expected results:
#userId contains the expected 12345678
#userName contains the expected The quick brown fox jumped over the lazy dog.
Executing it via C#:
using ( SqlConnection connection = new SqlConnection( "Server=localhost;Database=sandbox;Trusted_Connection=True;" ) )
using ( SqlCommand command = connection.CreateCommand() )
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.AuthenticatePhone" ;
SqlParameter phoneNumber = new SqlParameter {
ParameterName = "#phoneNumber" ,
IsNullable = true ,
Direction = ParameterDirection.Input ,
Value = 2125551212L ,
} ;
command.Parameters.Add( phoneNumber ) ;
SqlParameter userId = new SqlParameter {
ParameterName = "#User_ID" ,
IsNullable = true ,
Direction = ParameterDirection.Output ,
DbType = DbType.String ,
Size = 1000 ,
Value = DBNull.Value ,
} ;
command.Parameters.Add( userId ) ;
SqlParameter userName = new SqlParameter {
ParameterName = "#User_Name" ,
IsNullable = true ,
Direction = ParameterDirection.Output ,
DbType = DbType.String ,
Size = 1000 ,
Value = DBNull.Value ,
} ;
command.Parameters.Add( userName ) ;
connection.Open() ;
int rowsAffected = command.ExecuteNonQuery() ;
connection.Close() ;
Console.WriteLine( "Rows Affected: {0}" , rowsAffected ) ;
Console.WriteLine( "User ID: {{{0}}}" , userId.Value as string ) ;
Console.WriteLine( "User Name: {{{0}}}" , userName.Value as string ) ;
}
likewise results in the expected
Rows Affected: -1
User ID: {12345678}
User Name: {The quick brown fox jumped over the lazy dog.}
Even substituting your parameter definitions:
command.Parameters.Add("#phoneNumber", SqlDbType.BigInt).Value = 2125551212L ;
command.Parameters.Add("#User_ID", SqlDbType.Char, 8).Direction = ParameterDirection.Output;
command.Parameters.Add("#User_Name", SqlDbType.Char, 120).Direction = ParameterDirection.Output;
You get the expected results.
Though you might note that SqlDbType.Char is a SQL char(X). It's equivalent of `convert(char(120),'John Doe') in T-SQL. The .Net string will wind up padded with spaces to the specified length.
You might consider changing the type specifier to SqlDbType.VarChar: it will match the parameter declaration in the stored procedure and you won't find yourself needing to trim trailing whitespace from the string to make it useful.

change SqlDbType.Char to SqlDbType.VarChar
here:
scom.Parameters.Add("#User_ID", SqlDbType.Char, 8).Direction = ParameterDirection.Output;
scom.Parameters.Add("#User_Name", SqlDbType.Char, 120).Direction = ParameterDirection.Output;

As far as I know a char in .net is only one character long. So you will need to change the parameter type to varchar
scom.Parameters.Add("#User_ID", SqlDbType.Varchar, 8).Direction = ParameterDirect

Related

Procedure or function 'sp_Lab_InsertBiologicalPersonnel' expects parameter '#IcNumber', which was not supplied

I am trying to insert data into a SQL Server database by calling a stored procedure, but I am getting the error
Procedure or function 'sp_Lab_InsertBiologicalPersonnel' expects parameter '#IcNumber', which was not supplied
My stored procedure is called sp_Lab_InsertBiologicalPersonnel. I already check many time if there something missing, but still get same error, even make comparison with old code which is working. But for my code it say that error.
This is my C# code
public static PostApiResponse InsertBiologicalPersonel(Adapter ad, BiologicalPersonelInsert request, int creatorUserId)
{
var response = new PostApiResponse();
try
{
using (SqlCommand command = new SqlCommand("sp_Lab_InsertBiologicalPersonnel", ad.SQLConn, ad.SQLTran))
{
SqlParameter Param = new SqlParameter();
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter() { Value = request.biologicalId, ParameterName = "#biologicalId" });
command.Parameters.Add(new SqlParameter() { Value = request.IcNumber, ParameterName = "#IcNumber" });
command.Parameters.Add(new SqlParameter() { Value = request.Position, ParameterName = "#Position" });
command.Parameters.Add(new SqlParameter() { Value = creatorUserId, ParameterName = "#IdUserCreator" });
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
response.ResponseMessage = reader.GetString(0);
response.ReturnCode = reader.GetInt32(1);
response.Id = Convert.ToInt32(reader.GetValue(2));
}
reader.Close();
}
}
}
catch (Exception e)
{
throw e;
//string context = Common.ToStr(System.Web.HttpContext.Current);
//clsErrorLog.ErrorLog(context, e);
}
return response;
}
And this is my stored procedure:
ALTER PROCEDURE [dbo].[sp_Lab_InsertBiologicalPersonnel]
#biologicalId INT,
#IcNumber INT ,
#Position NVARCHAR(50),
#IdUserCreator INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ReturnCode Int
DECLARE #ReturnMessage NVARCHAR(200)
DECLARE #Identity INT
INSERT INTO [dbo].[Lab_BiologicalPersonnel]
([Id]
--,[Name]
,[IcNumber]
,[Position]
,[IdUserCreator]
,[IsDeleted]
,[IsEnabled])
VALUES
(#biologicalId
--,#Name
,#IcNumber
,#Position
,#IdUserCreator
,0
,1)
IF ##ROWCOUNT = 0
BEGIN
SET #ReturnCode = 1
SET #ReturnMessage = 'Insert Fail'
SET #Identity = 0
END
ELSE
BEGIN
SET #ReturnCode = 0
SET #ReturnMessage = 'Insert Success'
SET #Identity = (SELECT SCOPE_IDENTITY())
END
SELECT #ReturnMessage, #ReturnCode, #Identity
END
Please help me explain in quite simple, I'm a newbie in programming.

How can I get the Last Index of mysql that has been inserted to C# code behind?

So I have a MySql stored procedure for inserting a row:
DELIMITER $$
CREATE PROCEDURE AddPosition(
IN strName VARCHAR(1000)
,IN strPositionType VARCHAR(1000)
,OUT intPositionId INT
)
BEGIN
INSERT INTO positions (
positionName
, positionType
)
VALUES(
strName
,strPositionType
);
SET intPositionId = LAST_INSERT_ID();
END
Honestly, I'm not really sure if this SET intPositionId = LAST_INSERT_ID(); works, I want to get the value of IntPositionId and bring it to C#
in my c#;
public bool AddItem(Position data)
{
int newId = 0;
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "AddPosition";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("strName", data.PositionName).Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("strPositionType", data.PositionType).Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("intPositionId", SqlDbType.Int).Direction = ParameterDirection.Output;
try
{
MyHelper.MyExecuteNonQuery(cmd);
newId = (int) cmd.Parameters["intPositionId"].Value;
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return false;
}
}
The newId = (int) cmd.Parameters["intPositionId"].Value; says "Specified cast is not valid."
when I tried to use debugging to find out what cmd.Parameters["intPositionId"].Value; returns,
it is just plain object with no value. I guess the SET intPositionId = LAST_INSERT_ID(); didnt work.
so where did I go wrong here?

How to call procedure in aspx.cs file to return true or false when record found in database

i wrote a procedure which return 1 and 0 which given below
CREATE PROCEDURE [dbo].[CheckPI]
#PI Varchar(50)
AS BEGIN
SET NOCOUNT ON;
DECLARE #Exists INT
IF EXISTS(SELECT * FROM Tbl_ILSM_Quotation WHERE QuotationNo = #PI)
BEGIN
SET #Exists = 1
END
ELSE
BEGIN
SET #Exists = 0
END
RETURN #Exists
// when i execute this code in sql then it gives right ans
DECLARE #ReturnValue INT
EXEC #ReturnValue = #ReturnValue
SELECT #ReturnValue
END
and aspx.cs file
protected string GetPI()
{
int customerId = GetCustomerID(); // customer id - 123
int year = Convert.ToInt32(ddlIdYear.SelectedValue);
string PI = "PI/" + year + "/" + customerId; // PI - PI/2017/123
//SqlDataReader myReader = null;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["JSSConnection"].ToString());
con.Open();
SqlCommand cmd = new SqlCommand("CheckPI", con);
cmd.Parameters.AddWithValue("#PI", PI);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter sqlParam = new SqlParameter("#ReturnValue", DbType.Boolean);
sqlParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(sqlParam);
cmd.ExecuteNonQuery();
//int retrnval = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
//Response.Write(cmd.Parameters["#ReturnValue"].Value);
return PI;
}
i made procedure to check that pi number is available or not in database if available then return 1 otherwise 0
then i call that SP in aspx.cs file but i am unable to check that what it return after execution 1 or 0
// Add an Out param to capture the return value from the Procedure
SqlParameter outParam = new SqlParameter();
outParam.SqlDbType = System.Data.SqlDbType.Int;
outParam.ParameterName = “#outParam”;
outParam.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(outParam);
// Add an Out param to capture whether the Stored Proc executed correctly or not (exception)
SqlParameter retParam = new SqlParameter();
retParam.SqlDbType = System.Data.SqlDbType.Int;
retParam.ParameterName = “#retParam”;
retParam.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retParam);
// Execute the command
cmd.ExecuteNonQuery();
// Get the values
int retval = (int)cmd.Parameters[“#retParam”].Value;
int outval = (int)cmd.Parameters[“#outParam”].Value; // Should contain the value you've returned for existence of PI value
You've used INT to represent a boolean, you can change it to BIT within the Stored Proc to keep it consistent.
Instead of these lines:
SqlParameter sqlParam = new SqlParameter("#ReturnValue", DbType.Boolean);
sqlParam.Direction = ParameterDirection.Output;
use this:
SqlParameter sqlParam = new SqlParameter("#ReturnValue", DbType.Int32);
sqlParam.Direction = ParameterDirection.ReturnValue;
The value returned (with the RETURN statement) from the stored proc is always an integer, not a boolean (or string). So the type of the parameter needs to be changed. Plus you need the return value, as you didn't declare any output parameter, so you need a different direction.
Next you execute the query with
cmd.ExecuteNonQuery();
There is no select statement that returns values (everything after the RETURN in your stored proc is ignored), so this is enough.
After the execution, you can inspect the returned value:
int retVal = Convert.ToInt32(cmd.Parameters["#ReturnValue"].Value);
Then you can use that retVal variable, for instance by using return retVal == 1;. But then you need to change the return type of your method from string to bool.
i solved my problem. and answer is given below
Stored procedure
CREATE PROCEDURE [dbo].[CheckPI]
#PI Varchar(50),
#Exists INT = 0 out
AS BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM Tbl_ILSM_Quotation WHERE QuotationNo = #PI)
BEGIN
SET #Exists = 1
END
ELSE
BEGIN
SET #Exists = 0
END
and aspx.cs file code
protected string GetPI()
{
int customerId = GetCustomerID(); // customer id - 123
int year = Convert.ToInt32(ddlIdYear.SelectedValue);
string PI = "PI/" + year + "/" + customerId;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["JSSConnection"].ToString());
con.Open();
for (char i = 'A'; i <= 'Z'; i++)
{
PI = "PI/" + year + "/" + customerId + i; // PI - PI/2017/123
//SqlDataReader myReader = null;
SqlCommand cmd = new SqlCommand("CheckPI", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PI", PI);
SqlParameter outputParameter = new SqlParameter();
outputParameter.ParameterName = "#Exists";
outputParameter.SqlDbType = System.Data.SqlDbType.Int;
outputParameter.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(outputParameter);
cmd.ExecuteNonQuery();
int returnVal = Convert.ToInt32(outputParameter.Value.ToString());
if (returnVal == 1)
{
continue;
}
else
{
break;
}
}
//else
//{
// PI = "PI/" + year + "/" + customerId;
//}
con.Close();
//Response.Write(cmd.Parameters["#ReturnValue"].Value);
return PI;
}

ORA-06550 line 10, column 41: PLS-00103: Encountered the symbol "," when expecting one of the following:

I am executing an anonymous PL/SQL block from C# but I am getting an error like below:
ORA-06550 line 10, column 41: PLS-00103: Encountered the symbol ","
when expecting one of the following:
My code:
OracleDB AppConn = new OracleDB();
OracleDataReader eligiblereader = null;
string id = "2304502001101";
long provider = 667;
long policy = 150;
DateTime to = Convert.ToDateTime("2015/05/06");
using (OracleConnection con = AppConn.Connection)
{
OracleCommand cmd = con.CreateCommand();
cmd.Connection = con;
cmd.CommandText = #"declare
p_id VARCHAR2;
p_policy_id NUMBER;
p_provider_id NUMBER;
p_date DATE;
p_tob tob_type;
begin
pbm_pkg.get_member_tob(p_id,p_policy_id,p_provider_id,p_date,p_tob);
open :refcur for select tob_type.benefit_id from dual;
end;";
OracleParameter p = cmd.Parameters.Add(
"rs", OracleDbType.RefCursor,
DBNull.Value,
ParameterDirection.Output);
OracleParameter p_id = new OracleParameter();
p_id.OracleDbType = OracleDbType.Varchar2;
p_id.Direction = ParameterDirection.Input;
p_id.Value = id;
OracleParameter p_policy_id = new OracleParameter();
p_policy_id.OracleDbType = OracleDbType.Int64;
p_policy_id.Direction = ParameterDirection.Input;
p_policy_id.Value = policy;
OracleParameter p_provider_id = new OracleParameter();
p_provider_id.OracleDbType = OracleDbType.Int64;
p_provider_id.Direction = ParameterDirection.Input;
p_provider_id.Value = provider;
OracleParameter p_date = new OracleParameter();
p_date.OracleDbType = OracleDbType.Date;
p_date.Direction = ParameterDirection.Input;
p_date.Value = to;
cmd.Parameters.Add(p_id);
cmd.Parameters.Add(p_policy_id);
cmd.Parameters.Add(p_provider_id);
cmd.Parameters.Add(p_date);
try
{
con.Open();
cmd.ExecuteNonQuery();
eligiblereader = ((OracleRefCursor)cmd.Parameters[4].Value).GetDataReader();
while (eligiblereader.Read())
{
string id = eligiblereader.GetValue(0).ToString();
}
}
catch (Exception ex)
{
}
finally
{
con.Close();
}
return View();
}
The error is coming when the command is executing 'cmd.ExecuteNonQuery();'
I think I am missing something in anonymous block.
p_id VARCHAR2;
This is certainly incorrect syntax and will throw a compilation error.
Error reproduce:
SQL> DECLARE
2 p_id VARCHAR2;
3 BEGIN
4 NULL;
5 END;
6 /
p_id VARCHAR2;
*
ERROR at line 2:
ORA-06550: line 2, column 8:
PLS-00215: String length constraints must be in range (1 .. 32767)
SQL>
So, you must specify the string length constraint between 1 .. 32767.
Solution:
Specify the required length for the string variable.
SQL> DECLARE
2 p_id VARCHAR2(20);
3 BEGIN
4 NULL;
5 END;
6 /
PL/SQL procedure successfully completed.
SQL>
open :refcur for select tob_type.benefit_id from dual;
You need to declare the bind variable for the refcursor.
For example,
SQL> var r refcursor
SQL>
SQL> BEGIN
2 OPEN :r FOR SELECT empno,ename FROM emp;
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> print r
EMPNO ENAME
---------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL>

Why doesn't my C# code get a return value from my Oracle function?

I am trying to check if a user is in my database, my return value from my function is either a 't' or an 'f'. as below:
CREATE OR REPLACE FUNCTION LOGIN
(p_Naam in varchar2
,p_Wachtwoord in varchar2)
return varchar2
is
v_count number;
BEGIN
select count(*) into v_count
from Lid
where Naam = p_Naam
and Wachtwoord = p_Wachtwoord;
if v_count > 0 then
return 't';
end if;
return 'f';
END LOGIN;
now i call this function with my C# code as below:
public bool LogIn(string gebruikersnaam, string wachtwoord)
{
string s;
var cmd = new OracleCommand
{
Connection = conn,
CommandText = "Login",
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.Add("p_Naam", OracleDbType.Varchar2).Value = gebruikersnaam;
cmd.Parameters.Add("p_Wachtwoord", OracleDbType.Varchar2).Value = wachtwoord;
cmd.Parameters.Add("return_value", OracleDbType.Varchar2, ParameterDirection.ReturnValue);
try
{
conn.Open();
cmd.ExecuteNonQuery();
s = cmd.Parameters["return_value"].Value.ToString();
}
finally
{
conn.Close();
}
return s == "t";
}
when i try this funcion within my oracle developer i get an output.
only in my C# code, s always comes out as ""
in my sql developer the following gives me 't'
BEGIN
dbms_output.put_line(LOGIN('Willem Koonings', 'willem'));
END;
I haven't been working with OracleCommands for a while, but i would suggest this change:
CommandText = "Login(:p_Naam, :p_Wachtwoord)";
The long solution which I bets works (change type to text though):
CommandText = "select Login(:p_Naam, :p_Wachtwoord) return_value from dual";
When you have this in your code:
s = cmd.Parameters["return_value"].Value.ToString();
It implies, to me, that your command had somethink akin to this:
insert into test (user_name, create_date)
values (:USERNAME, sysdate)
returning user_id into :return_value
I've never seen a stored procedure use a "returning" as such. That doesn't automatically mean it can't be done, but it doesn't seem consistent with how I've used it and seen it used.
Since you are running a stored proc that returns a scalar value, this would probably suit you better:
string result = (string)cmd.ExecuteScalar();
You need to place the "return value" parameter first in the index, as far as i can tell from working with Oracle it doesn't pass the names of the parameters to the Oracle call, it is absolute placing.
Hope this solves your problems :)
Dom
ParameterDirection.ReturnValue could return only a numeric value, not a string or single char.
(At least in Sql Server). Try to change your function to return an integer and your parameters collection to receive an integer. (I don't have Oracle to test, please correct me if there are some syntax errors)
See this reference (for Sql Server)
CREATE OR REPLACE FUNCTION LOGIN
(p_Naam in varchar2
,p_Wachtwoord in varchar2)
return INTEGER
is
v_count number;
BEGIN
select count(*) into v_count
from Lid
where Naam = p_Naam
and Wachtwoord = p_Wachtwoord;
if v_count > 0 then
return 1;
end if;
return 0;
END LOGIN;
....
cmd.Parameters.Add("p_Naam", OracleDbType.Varchar2).Value = gebruikersnaam;
cmd.Parameters.Add("p_Wachtwoord", OracleDbType.Varchar2).Value = wachtwoord;
cmd.Parameters.Add("return_value", OracleDbType.Int32, ParameterDirection.ReturnValue);
....
int result = Convert.ToInt32(cmd.Parameters["return_value"].Value);
if(result == 0)
// fail
else
// success...
Instead of 'Return' statement why don't you declare a out parameter .Let me know if iam not clear
Just found out this and tested with VS2017 Community edition + 11g.
OracleCommand chkCmd = null;
try
{
chkCmd = new OracleCommand();
chkCmd.CommandText = "login";
chkCmd.CommandType = CommandType.StoredProcedure;
chkCmd.Connection = conn;
OracleParameter mobParam1 = new OracleParameter("p_Naam", OracleDbType.Varchar2, 2000);
mobParam1.Direction = ParameterDirection.Input;
mobParam1.Value = gebruikersnaam;
OracleParameter mobParam2 = new OracleParameter("p_Wachtwoord", OracleDbType.Varchar2, 2000);
mobParam2.Direction = ParameterDirection.Input;
mobParam2.Value = wachtwoord;
OracleParameter retValue = new OracleParameter("returnVal", OracleDbType.Varchar2, 2000);
retValue.Direction = ParameterDirection.ReturnValue;
chkCmd.Parameters.Clear();
chkCmd.Parameters.Add(retValue);
chkCmd.Parameters.Add(mobParam1);
chkCmd.Parameters.Add(mobParam2);
con.Open();
chkCmd.ExecuteScalar();
string retmsg = Convert.ToString(retValue.Value);
return retmsg=="t";
}
finally
{
con.Close();
chkCmd.Dispose();
con.Dispose();
}
Make Return_Value your first parameter:
cmd.Parameters.Add("Return_Value", OracleDbType.Boolean, ParameterDirection.ReturnValue);

Categories

Resources