I've created a function in plpgsql and I'm trying to call the stored procedure from .net core api
But I'm getting following exception in c#
42883: function proc_insert_test(brndcode => integer, brndname => character varying, brndsname => character varying, prdtype => character, discontinue => character, crddate => date, status => integer, recstat => integer, brndgrpseqno => integer, wefrom => date) does not exist
No function matches the given name and argument types. You might need to add explicit type casts.
Procedure:
CREATE OR REPLACE FUNCTION public.proc_insert_test(p_brndcode integer,
p_brndname varchar(100),
p_brndsname varchar(100),
p_prdtype char(1),
p_discontinue char(1),
p_crddate date,
p_status integer,
p_recstat integer,
p_brndgrpseqno integer,
p_wefrom date)
RETURNS char
LANGUAGE plpgsql
AS $body$
BEGIN
Insert into arc_mmstbrndgroup(brndcode, brndname, brndsname, prdtype, discontinue, crddate, status, recstat, brndgrpseqno, wefrom)
values(p_brndcode, p_brndname, p_brndsname, p_prdtype, p_discontinue, p_crddate, p_status, p_recstat, p_brndgrpseqno, p_wefrom);
return 'saved';
END;
$body$
;
Procedure calling from c#:
NpgsqlCommand cmd = new NpgsqlCommand("proc_insert_test", _connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#brndcode", NpgsqlTypes.NpgsqlDbType.Integer, 123);
cmd.Parameters.AddWithValue("#brndname", NpgsqlTypes.NpgsqlDbType.Varchar, 100, "Test3");
cmd.Parameters.AddWithValue("#brndsname", NpgsqlTypes.NpgsqlDbType.Varchar, 100, "Test3");
cmd.Parameters.AddWithValue("#prdtype", NpgsqlTypes.NpgsqlDbType.Char, 1, "T");
cmd.Parameters.AddWithValue("#discontinue", NpgsqlTypes.NpgsqlDbType.Char, 1, "T");
cmd.Parameters.AddWithValue("#crddate", NpgsqlTypes.NpgsqlDbType.Date, DateTime.Now);
cmd.Parameters.AddWithValue("#status", NpgsqlTypes.NpgsqlDbType.Integer, 1);
cmd.Parameters.AddWithValue("#recstat", NpgsqlTypes.NpgsqlDbType.Integer, 9);
cmd.Parameters.AddWithValue("#brndgrpseqno", NpgsqlTypes.NpgsqlDbType.Integer, 1234);
cmd.Parameters.AddWithValue("#wefrom", NpgsqlTypes.NpgsqlDbType.Date, DateTime.Now);
_connection.Open();
cmd.ExecuteNonQuery();
cmd.Dispose();
_connection.Close();
What can be the issue?
I'm also faced this issue. After some analyze found that date datatype casting not working. So we changed our calling method like this,
Without return value:
string strquery = "SELECT PROC_INSERT_TEST(123,'Test3','Test3','T','T',";
strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "',1,9,1234,";
strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "')";
NpgsqlCommand cmd = new NpgsqlCommand(strquery, _connection);
_connection.Open();
cmd.ExecuteNonQuery();
cmd.Dispose();
_connection.Close();
With return value
string strquery = "BEGIN; SELECT PROC_INSERT_TEST_WITH_RETURN(123,'Test3','Test3','T','T',";
strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "',1,9,1234,";
strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "')";
NpgsqlCommand cmd = new NpgsqlCommand(strquery, _connection);
_connection.Open();
object cursorVal = cmd.ExecuteScalar();
DataSet ds = FetchAll(_connection, cursorVal);
cmd.Dispose();
_connection.Close();
private DataSet FetchAll(NpgsqlConnection _connection, object cursorVal)
{
try
{
DataSet actualData = new DataSet();
string strSql = "fetch all from \"" + cursorVal + "\";";
NpgsqlCommand cmd = new NpgsqlCommand(strSql, _connection);
NpgsqlDataAdapter ada = new NpgsqlDataAdapter(cmd);
ada.Fill(actualData);
return actualData;
}
catch (Exception Exp)
{
throw new Exception(Exp.Message);
}
}
For me It is working
PGDbContext _context = new PGDbContext();
string d1 = "mm5";
string d2 = "mmTest6";
int d3 = 11;
string d4 = "1";
var DistributionChannelGUID = _context.Database.SqlQuery<List<string>>("call dbo.insupdelglclassmaster({0},{1},{2},{3})", d1, d2, d3, d4).ToList();
if function have
Param1 character varying DEFAULT array[]::character varying[]
then how to skip to pass from c#.
Related
I am trying to load data from access database with query using CAST to change the datatype to date in c#.But when i typed in the textbox to enter the parameter for date for the parameters it gives me ierrorinfo.getdescription failed with e_fail.
Code
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string start = textBox1.Text;
string end = textBox2.Text;
string query = "SELECT dbo_RSWORKORDERCUR.workordercurID,dbo_RSWORKORDERCUR.workordercode,CAST(dbo_RSWORKORDERCUR.closeDtime AS DATE) AS [Close Date],CAST(dbo_RSWORKORDERCUR.RequiredbyDtime AS DATE) AS [Required By Date] " +
"FROM dbo_RSWORKORDERCUR1 " +
"WHERE (((CAST(dbo_RSWORKORDERCUR.closeDtime AS DATE))>=#start And (CAST(dbo_RSWORKORDERCUR.closeDtime AS DATE))<=#end));";
command.Parameters.Add(new OleDbParameter("#start", start));
command.Parameters.Add(new OleDbParameter("#end", end));
command.CommandText = query;
OleDbDataAdapter da = new OleDbDataAdapter(command);
DataTable dt5 = new DataTable();
da.Fill(dt5);
dataGridView1.DataSource = dt5;
connection.Close();
I see no reason to cast the values. Use DateTime when dealing with date and time:
DateTime start = DateTime.Parse(textBox1.Text);
DateTime end = DateTime.Parse(textBox2.Text);
string query = "SELECT dbo_RSWORKORDERCUR.workordercurID,dbo_RSWORKORDERCUR.workordercode,dbo_RSWORKORDERCUR.closeDtime, dbo_RSWORKORDERCUR.RequiredbyDtime " +
"FROM dbo_RSWORKORDERCUR1 " +
"WHERE dbo_RSWORKORDERCUR.closeDtime >= #start And dbo_RSWORKORDERCUR.closeDtime <= #end;";
command.Parameters.Add(new OleDbParameter("#start", OleDbType.Date));
command.Parameters.Add(new OleDbParameter("#end", OleDbType.Date));
command.Parameters["#start"].Value = start;
command.Parameters["#end"].Value = end;
i have a button that when clicked inserts data from textbox and combobox fields into database tables, but every time i insert it gives me "Invalid attempt to call read when reader is closed". How can i get rid of this error. And tips on optimising the code are welcome, because i know im a total noob. thanks
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query1 = "insert into location(Storage, Shelf, columns, rows) values(" + txtWarehouse.Text + ", " + txtShelf.Text + ", " + txtColumn.Text + ", " + txtRow.Text + ")";
SqlCommand sqlCmd = new SqlCommand(Query1, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
sqlCon.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query3 = "SELECT LOCATION_ID FROM LOCATION WHERE storage='" + txtWarehouse.Text + "' AND shelf='" + txtShelf.Text + "' AND columns='"
+ txtColumn.Text + "' AND rows='" + txtRow.Text + "'";
SqlCommand sqlCmd1 = new SqlCommand(Query3, sqlCon);
SqlDataReader dr = sqlCmd1.ExecuteReader(); ;
while (dr.Read())
{
string LocationId = dr[0].ToString();
dr.Close();
string Query2 = "insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID) values ('" + txtSku.Text + "','" + txtNimetus.Text + "', '"
+ txtMin.Text + "', '" + txtMax.Text + "', '" + txtQuan.Text + "', '" + LocationId + "', '" + (cbCat.SelectedIndex+1) + "', '" + (cbMail.SelectedIndex+1) + "')";
SqlCommand sqlCmd = new SqlCommand(Query2, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
}
sqlCon.Close();
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
Let's try to make some adjustments to your code.
First thing to consider is to use a parameterized query and not a
string concatenation when you build an sql command. This is mandatory
to avoid parsing errors and Sql Injections
Second, you should encapsulate the disposable objects in a using statement
to be sure they receive the proper disposal when you have finished to
use them.
Third, you can get the LOCATION_ID from your table without running a
separate query simply adding SELECT SCOPE_IDENTITY() as second batch to your first command. (This works only if you have declared the LOCATION_ID field in the first table as an IDENTITY column)
Fourth, you put everything in a transaction to avoid problems in case
some of the code fails unexpectedly
So:
SqlTransaction tr = null;
try
{
string cmdText = #"insert into location(Storage, Shelf, columns, rows)
values(#storage,#shelf,#columns,#rows);
select scope_identity()";
using(SqlConnection sqlCon = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(cmdText, sqlCon))
{
sqlCon.Open();
using( tr = sqlCon.BeginTransaction())
{
// Prepare all the parameters required by the command
cmd.Parameters.Add("#storage", SqlDbType.Int).Value = Convert.ToInt32(txtWarehouse.Text);
cmd.Parameters.Add("#shelf", SqlDbType.Int).Value = Convert.ToInt32(txtShelf.Text);
cmd.Parameters.Add("#columns", SqlDbType.Int).Value = Convert.ToInt32(txtColumn.Text );
cmd.Parameters.Add("#rows", SqlDbType.Int).Value = Convert.ToInt32(txtRow.Text);
// Execute the command and get back the result of SCOPE_IDENTITY
int newLocation = Convert.ToInt32(cmd.ExecuteScalar());
// Set the second command text
cmdText = #"insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID)
values (#sku, #nimetus,#min,#max,#qty,#locid,#catid,#ordid)";
// Build a new command with the second text
using(SqlCommand cmd1 = new SqlCommand(cmdText, sqlCon))
{
// Inform the new command we are inside a transaction
cmd1.Transaction = tr;
// Add all the required parameters for the second command
cmd1.Parameters.Add("#sku", SqlDbType.NVarChar).Value = txtSku.Text;
cmd1.Parameters.Add("#nimetus",SqlDbType.NVarChar).Value = txtNimetus.Text;
cmd1.Parameters.Add("#locid", SqlDbType.Int).Value = newLocation;
.... and so on for the other parameters required
cmd1.ExecuteNonQuery();
// If we reach this point the everything is allright and
// we can commit the two inserts together
tr.Commit();
}
}
}
}
catch (Exception er)
{
// In case of exceptions do not insert anything...
if(tr != null)
tr.Rollback();
MessageBox.Show(er.Message);
}
Notice that in the first command I use parameters of type SqlDbType.Int because you haven't used single quotes around your text. This should be verified against the real data type of your table columns and adjusted to match the type. This is true as well for the second command where you put everything as text albeit some of those fields seems to be integer (_location_id_ is probably an integer). Please verify against your table.
I try to call my oracle function, but for some reason i get wiered results from it.
This is my C# code :
using (OracleConnection _conn = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.20.190.2)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=DBIDB)));User Id=blng;Password=blng;"))
{
using (OracleCommand cmd = new OracleCommand())
{
_conn.Open();
cmd.Connection = _conn;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "PKG_update_switch.checkexistsinswitch";
cmd.Parameters.Add("phone", OracleDbType.Varchar2, ParameterDirection.Input).Value = phoneToQuery;
cmd.Parameters.Add("res", OracleDbType.Int32, ParameterDirection.ReturnValue);
cmd.ExecuteNonQuery();
result = cmd.Parameters["res"].Value.ToString();
Debug.WriteLine("---" + result);
if (result.Equals("null"))
message = "Didnt find number";
else
message = "Found " + phoneToQuery + " in " + result;
MessageBox.Show(message, "Check Phone Exists",
MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
_conn.Close();
}
}
As a result i always get 0, witch is imposible.
Oracle function:
function checkExistsInSwitch(phone in varchar2) RETURN integer is
tmp varchar2(100):='';
begin
for t in (select c.re_collection_id from re_collection_values c where c.start_range = phone)
loop
----- check that the number is from folder number 2
begin
select o.network_identifier into tmp from operators o where o.switch_folder_id = t.re_collection_id;
return 11;--tmp;
exception
when others then
null;
end;
end loop;
return 11;--'';
end;
this is very wiered, for a stored procedure i get good results, this only happend to my with the stored functions.
I got this error mess "Invalid length parameter passed to LEFT or SUBSTRING function" from this below. Anyone can give me a hint what cause this, and how I can solve it?
string cmdText = #"Declare #SqlString nvarchar(2500)
, #AreaDelimiter char(1)
, #AreaFilter nvarchar(max);
Select #AreaDelimiter = ','
If (#AreaName Not Like '*')
Begin
Set #AreaName = #AreaName + #AreaDelimiter
Set #AreaFilter = ''
While LEN(#AreaName) > 0
Begin
If (Len(#AreaFilter) > 0)
Begin
Set #AreaFilter = #AreaFilter + ' Or Area Like ''' +
LTRIM(SubString(#AreaName, 1,
CharIndex(#AreaDelimiter, #AreaName) - 1)) + '%'''
End
Else
Begin
Set #AreaFilter = 'Area Like ''' +
LTRIM(SubString(#AreaName, 1,
CharIndex(#AreaDelimiter, #AreaName) - 1)) + '%'''
End
Select #AreaName = SUBSTRING(#AreaName, CharIndex(#AreaDelimiter,
#AreaName) + 1, Len(#AreaName))
End
End"
this code above continues with the else statement and the others operations who works :)
And this is my C# code:
string area = "AREA1,AREA2,AREA3";
using (SqlConnection conn = new SqlConnection(domain.getDecryptedSqlConnectionString(domain.name + passPhrase)))
{
using (SqlCommand cmd = new SqlCommand(cmdText, conn))
{
System.Globalization.CultureInfo cInfo = new System.Globalization.CultureInfo("pt-BR");
DateTime dt = DateTime.Parse(startDate, cInfo);
DateTime da = DateTime.Parse(endDate, cInfo);
cmd.Parameters.Add("Interval", SqlDbType.Int).Value = interval;
cmd.Parameters.Add("IntervalUnit", SqlDbType.VarChar).Value = intervalUnit;
cmd.Parameters.Add("StartDate", SqlDbType.DateTime).Value = dt.ToShortDateString();
cmd.Parameters.Add("EndDate", SqlDbType.DateTime).Value = da.ToShortDateString();
cmd.Parameters.Add("tbName", SqlDbType.VarChar).Value = domain.alarmTableName;
cmd.Parameters.Add("AreaName", SqlDbType.VarChar).Value = area;
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
using (DataTable tb = new DataTable())
{
try
{
conn.Open();
adapter.Fill(tb);
return tb;
}
catch (Exception ex)
{
return tb;
}
finally
{
conn.Close();
}
}
}
}
}
SOLVED, I JUST CHANGE
cmd.Parameters.Add("AreaName", SqlDbType.VarChar).Value = area;
FOR
cmd.Parameters.Add("AreaName", SqlDbType.VarChar, -1).Value = area;
I can reproduce the error with
DECLARE #AreaName VARCHAR(20);
DECLARE #AreaDelimiter CHAR(1);
DECLARE #AreaFilter VARCHAR(100);
SET #AreaName='AREA1,AREA2,AREA3,area4,area5';
SET #AreaDelimiter=',';
Notice that the declaration of #AreaName is not long enough for the data - check your declaration.
Also, if the string for #AreaName has come from user input, your code is vulnerable to SQL injection attacks.
EDIT:
All your SQL parameter names need to start with #, e.g. #AreaName, and you must match up the SqlDbType between your C# code and the SQL code.
You shouldn't be using
cmd.Parameters.Add("StartDate", SqlDbType.DateTime).Value = dt.ToShortDateString();
instead it should be
cmd.Parameters.Add("StartDate", SqlDbType.DateTime).Value = dt;
because dt is already a DateTime.
I wrote this procedure in a site. it take a string as input parameter(user name) and looks into the related table to find out it's record and return the "ID" field as output of procedure.
this work fine but there's one (major) problem, which is when it take a input in other English language, it can't find the target record and return "-1" as output.
The visitors use Persian language and i observed it in my SQLserver. The collation is "Persian_100_CI_AI" and my string fields are "nvarchar".
what should i do to solve this problem?
i'm using SQL-Server 2008.
thanks a lot
protected int GetThisUserID(string uname)
{
string returnvalue = "";
int returnintegervalue = -1;
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["OldEagleConnectionString"].ToString());
try
{
//SqlCommand command = new SqlCommand("SELECT [ID] FROM [Customers] WHERE ([Uname] = '" + User.Identity.Name.ToString() + "'", connection);
//SqlCommand command = new SqlCommand("SELECT * FROM [Customers] WHERE ([Uname] = '" + User.Identity.Name.ToString() + "')", connection);
SqlCommand command = new SqlCommand("SELECT * FROM [Customers] WHERE ([Uname] = '" + uname + "')", connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
returnvalue = reader["ID"].ToString();
returnintegervalue = Int32.Parse(returnvalue);
}
}
}
catch (SqlException ex)
{
Response.Write(ex.Message.ToString());
returnvalue = ex.Message.ToString();
}
finally
{
connection.Close();
SqlConnection.ClearPool(connection);
}
return returnintegervalue;
}
I hate to answer my own question but here it is:
have to add a N in select command, just like this:
SqlCommand command = new SqlCommand("SELECT * FROM [Customers] WHERE ([Uname] = N'" + uname + "')", connection);
problem solved!
Without the N, the string is taken to be a varchar, and the conversion loses characters outside of that supported by the varchar encoding of the database.