Passing a boolean parameter to a SQL Server stored procedure - c#

I asked this question earlier and I thought I found what the problem was, but I didn't. I'm having a problem passing a boolean parameter to a stored procedure. Here's my c# code:
public bool upload = false;
protected void showDate(object sender, EventArgs e)
{
if (Radio1.Checked)
{
upload = true;
Radio2.Checked = false;
date_div.Visible = true;
date_div2.Visible = false;
}
}
protected void getMonthList()
{
selectedYear = year.SelectedValue.ToString();
SqlConnection connection = new SqlConnection(connString);
SqlCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
connection.Open();
cmd.CommandText = "getMonth";
cmd.Parameters.Add("#year", SqlDbType.Int, 0).Value = Convert.ToInt32(selectedYear);
cmd.Parameters.AddWithValue("#upload", upload);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
month.DataSource = dt;
month.DataTextField = "month";
month.DataValueField = "monthValue";
month.DataBind();
month.Items.Insert(0, new ListItem("Select", "0"));
}
And this is the stored procedure getMonth:
ALTER PROCEDURE [dbo].[getMonth]
#year int,
#upload Bit
AS
BEGIN
IF #upload = 1
BEGIN
SELECT distinct datename(mm, Upload_date) month
,month (upload_date) monthValue
FROM dbo.RESOLVED
WHERE datepart(yyyy, upload_date) = #year
ORDER by 2
END
ELSE
BEGIN
SELECT distinct datename(mm, substring(CREATE_DT,1,2) + '.' + substring(CREATE_DT,3,2) + '.' + substring(CREATE_DT,5,4)) month
,month (substring(CREATE_DT,1,2) + '.' + substring(CREATE_DT,3,2) + '.' + substring(CREATE_DT,5,4)) monthValue
FROM dbo.RESOLVED
WHERE datepart(yyyy, substring(CREATE_DT,1,2) + '.' + substring(CREATE_DT,3,2) + '.' + substring(CREATE_DT,5,4)) = #year
ORDER by 2
END
The stored procedure is supposed to populate dropdownlist. It supposed to execute the IF statement, but IF is skipped and ELSE is executed instead.

I'd be inclined to specify the type for the boolean parameter also. Maybe something like;
SqlParameter param = new SqlParameter();
param.ParameterName = "#upload";
param.Value = upload;
param.DbType = System.Data.DbType.Boolean
cmd.Parameters.Add(param);
Maybe also check using a breakpoint or even System.Diagnostics.Debug.Write("#Upload is " + upload) to ensure you are passing in what you think you are passing in.
Lastly, I'd suggest putting your SqlConnection and SqlCommand statments in a using block to ensure the resources are cleaned up after this has run.

Related

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;
}

Why Is this returning no results when executed?

SqlConnection conn = getConnection();
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SP_PSLA_SEARCH"; //The stored procedure gets added
cmd.CommandTimeout = 0;
cmd.Connection = conn;
// Start adding the parameters of the stored procedure
cmd.Parameters.AddWithValue("#usrnm", thisUser.Username);
int constit = 0;
if (thisUser.Constituencies.Count > 0)
{
foreach (KeyValuePair<int, string> kp in thisUser.Constituencies)
{
if (kp.Value == ddlConstituency.SelectedValue.ToString())
{
constit = kp.Key;
break;
}
}
}
cmd.Parameters.AddWithValue("#cnstncy", constit);
string pdval = null;
int valtype = 0;
if (rbsearchradios.SelectedIndex == 0)
{
try
{
pdval = searchVal;
cmd.Parameters.AddWithValue("#Search", DBNull.Value);
cmd.Parameters.AddWithValue("#pd", int.Parse(pdval));
cmd.Parameters.AddWithValue("#type", valtype);
}
catch
{
System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), "stop", "alert('Invalid PD Number Supplied! Please Provide A Valid Submission.');", true);
return;
}
}
else
{
valtype = 1;
cmd.Parameters.AddWithValue("#Search", searchVal);
cmd.Parameters.AddWithValue("#pd", DBNull.Value);
cmd.Parameters.AddWithValue("#type", valtype);
}
cmd.Parameters.AddWithValue("#app", 1);
conn.Open();
// Creates Dataadapter for execution
SqlDataAdapter dp2 = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
dp2.Fill(ds, "name");
I am trying to the arguments of the stored procedure and the having this stored procedure execute and get this results into a dataset but I get nothing.. Literally. There are no exceptions, just no result from the stored procedure.
This is the stored procedure:
DECLARE #return_value int
EXEC #return_value = [dbo].[SP_PSLA_SEARCH]
#usrnm = N'tstone',
#cnstncy = 55,
#Search = N'primary',
#pd = NULL,
#type = 1,
#app = 1
SELECT 'Return Value' = #return_value
GO
To troubleshoot:
Make sure what values has each parameter and execute the same query directly against database in Sql Server Management Studio.
Check if you properly use the result from the dataset (it's not clear from the code)
In general, you can also try to simplify and make your code more clear:
the block with return and if (rbsearchradios.SelectedIndex == 0) can be moved at the beginning, it makes no sense to create SqlCommand and then break
if SP returns only single value, you can use the ExecuteScalar() method, which is faster and straightforward.

Return an sql variable's value from within an Oracle Sql Query back to .NET code

For the past few hours I am trying to do the simplest of the simple things (at least for SQL SERVER) in an Oracle Data Base, through a .NET application using ADO.NET. It seems impossible.
For SQL SERVER I would do this simple task, supposing I have an SqlCommand object
comm.CommandText = #"
DECLARE #next_id INT
SET #next_id = (SELECT ISNULL(MAX(id_col),0) FROM TABLE_1) + 1
INSERT INTO TABLE_1 (id_col, col1, ...) VALUES (#next_id, val1, ...)
SELECT #next_id";
int id = Convert.ToInt32(comm.ExecuteScalar());
That would insert a new record to table TABLE_1 and I would take back the new id in the "id" variable in c# code.
Four simple steps
Declare a variable
Set it to the next available id
Insert the record with the new variable
Return the variable's value
Ok I managed to declare the variable in Oracle query. Also I (think) I managed to give it a value (With SELECT INTO)
How can I get back this variable's value back in c#? How can i SELECT a variable's value to the output stream in Oracle SQL?
I know that there are better ways to achieve getting back an identity column, but that's not the question here. It could be a totally different example. The question is simple.: I have declared a variable inside an oracle sql script that will be executed from within .net app. How can i get the variable's value back to c#, from an oracle query? What is the above code's equivalent with Oracle ADO.NET query?
You'll want to use ODP.NET (Oracle's Oracle Data Access Components):
An example of this is below. Note that in ODP.NET, you can establish a parameters direction (input, inputoutput, output, returnvalue) to correspond with the parameters of the procedure or statement you're running. In this example, I'm grabbing a returnvalue, which is an ID that is generated by the db via a sequence and trigger (its created automagically as far as the .NET app is concerned):
int event_id = 0;
using (OracleConnection oraConn = new OracleConnection(connStr))
{
string cmdText = #"insert into EVENT
(EVENT_NAME, EVENT_DESC)
values
(:EVENT_NAME, :EVENT_DESC)
RETURNING EVENT_ID INTO :EVENT_ID
";
using (OracleCommand cmd = new OracleCommand(cmdText, oraConn))
{
oraConn.Open();
OracleTransaction trans = oraConn.BeginTransaction();
try
{
OracleParameter prm = new OracleParameter();
cmd.BindByName = true;
prm = new OracleParameter("EVENT_NAME", OracleDbType.Varchar2);
prm.Value = "SOME NAME"; cmd.Parameters.Add(prm);
prm = new OracleParameter("EVENT_DESC", OracleDbType.Varchar2);
prm.Value = "SOME DESC"; cmd.Parameters.Add(prm);
prm = new OracleParameter( "EVENT_ID"
, OracleDbType.Int32
, ParameterDirection.ReturnValue);
cmd.Parameters.Add(prm);
cmd.ExecuteNonQuery();
trans.Commit();
// return value
event_id = ConvertFromDB<int>(cmd.Parameters["EVENT_ID"].Value);
}
catch
{
trans.Rollback();
throw;
}
finally
{
trans.Dispose();
}
oraConn.Close();
}
}
The ConvertFromDB is just a generic to cast the return value to its .NET equivalent (an int in this case).
Hope that helps.
EDIT:
You can easily bind an array of values (and retrieve an array of return values) in ODP.NET:
using (OracleConnection oraConn = new OracleConnection(connStr))
{
string cmdText = #"insert into TEST_EVENT
(EVENT_NAME, EVENT_DESC)
values
(:EVENT_NAME, :EVENT_DESC)
RETURNING EVENT_ID INTO :EVENT_ID
";
using (OracleCommand cmd = new OracleCommand(cmdText, oraConn))
{
oraConn.Open();
OracleTransaction trans = oraConn.BeginTransaction();
try
{
string[] event_names = new string[2];
string[] event_descs = new string[2];
int[] event_ids = new int[2];
event_names[0] = "Event1";
event_descs[0] = "Desc1";
event_names[1] = "Event2";
event_descs[1] = "Desc2";
OracleParameter prm = new OracleParameter();
cmd.Parameters.Clear();
cmd.ArrayBindCount = 2;
cmd.BindByName = true;
prm = new OracleParameter("EVENT_NAME", OracleDbType.Varchar2);
prm.Value = event_names; cmd.Parameters.Add(prm);
prm = new OracleParameter("EVENT_DESC", OracleDbType.Varchar2);
prm.Value = event_descs; cmd.Parameters.Add(prm);
prm = new OracleParameter( "EVENT_ID"
, OracleDbType.Int32
, ParameterDirection.ReturnValue);
cmd.Parameters.Add(prm);
cmd.ExecuteNonQuery();
trans.Commit();
// get return values
event_ids = (int[])(cmd.Parameters["EVENT_ID"].Value);
}
catch
{
trans.Rollback();
throw;
}
finally
{
trans.Dispose();
}
oraConn.Close();
}
}

Populating WPF datagrid from SQLCommand using stored procedure

I'm currently trying to populate a datagrid using a member of a class that uses SQLCommand to execute a stored procedure and return the results.
My class member (and where I believe the issues lies) is:
public DataView DisplayHealthIndicator(DateTime startDate, DateTime endDate)
{
string queryString =
"DECLARE #RC int"
+ "DECLARE #date_from datetime = dateadd(day, 0, datediff(day, 0, getdate()))"
+ "DECLARE #date_to datetime = dateadd(day, 0, datediff(day, 0, getdate()))"
+ "EXECUTE #RC = [Testing].[marlin].[support_retrieve_workflow_history] "
+ "#date_from "
+ ",#date_to"
+ "GO";
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
using (var cmd = new SqlCommand(queryString, connection))
{
connection.Open();
var reader = cmd.ExecuteReader();
var dt = new DataTable();
dt.Load(reader);
return dt.DefaultView;
}
}
}
and I'm calling this member using:
var db = new DatabaseHandle();
dataGridWorkflow.ItemsSource = db.DisplayHealthIndicator(DateTime.Now, DateTime.Now);
However! I'm currently receiving the error:
Incorrect syntax near #date_from
Must declare the scalar variable #RC
To a degree I understand the error - I believe that I can't declare variables in my sqlQuery string... but then, how do I do this?
I'm fairly sure that it doesn't have any bearing on this, but in case it does, this is the contents of the stored procedure:
create procedure marlin.support_retrieve_workflow_history
(
#date_from datetime,
#date_to datetime
)
as
select dateadd(day, 0, datediff(day, 0, e.event_date)) as 'Date',
c.setting_secondary 'Workflow Category' ,
d.setting_main as 'Error Type' ,
sum(e.event_count) as 'Total'
from marlin.support_events e
inner join marlin.support_config c
on e.event_category = c.setting_code
and c.config_code = 60
inner join marlin.support_config d
on e.event_type = d.setting_code
and d.config_code = 70
where e.event_date between #date_from and #date_to
group by
e.event_date,
c.setting_secondary ,
d.setting_main
cmd.Parameters["#ReturnValue"] contains the return value - you don't need to add a parameter in dynamic SQL
Add your parameters to the cmd
cmd.Parameters.AddWithValue("ParamName", Value);
Also change the cmd.CommandType (might not be called that, check members of cmd) to StoredProcedure
e.g.
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
using (var cmd = new SqlCommand(queryString, connection))
{
connection.Open();
cmd.CommandType = ??.StoredProcedure; // Can't remember what enum name is prob SqlCommandType or something
cmd.Parameters.AddWithValue("date_from", DateTime.blah.blah);
cmd.Parameters.AddWithValue("date_to", DateTime.blah.blah);
var reader = cmd.ExecuteReader();
var dt = new DataTable();
dt.Load(reader);
return dt.DefaultView;
}
}
Disclaimer: Some of these prop names, the name of the return value param might not be correct so check the docs :)
This post is a bit old...But, I wanted to share how I am dynamically populating the WPF DataGrid
private void Fill_DataGrid_ServiceName()
{
this.Cursor = Cursors.Wait;
// create an instance
DatabaseClass objDatabaseClass = new DatabaseClass(_connectionString);
// if we are able to open and close the SQL Connection then proceed
if (objDatabaseClass.CheckSQLConnection())
{
try
{
// create an instance. variable 'con' will hold the instance
SqlConnection con = new SqlConnection(_connectionString);
con.Open();
// Query to populate the Grid
string Query = #"SELECT
cm_mktdata_mdsservice_fits_to_finance_id_unique AS [Id Unique]
,cm_mktdata_mdsservice_fits_to_finance_MDSService_fits AS [FITS MDSService]
,cm_mktdata_mdsservice_fits_to_finance_MDSService_finance AS [Finance MDSService]
,'[ ' + CONVERT(varchar, user_detail_user_info_id_user) + ' ] ' + user_detail_user_info_nm_login AS [Last Modified By]
,cm_mktdata_mdsservice_fits_to_finance_record_version AS [Record Version]
,cm_mktdata_mdsservice_fits_to_finance_dt_modified AS [Dt Modified]
,cm_mktdata_mdsservice_fits_to_finance_ind_active AS [Ind Active]
FROM
dbo.v_mktdata_ui_mdsservice_fits_to_finance_detail
WHERE
cm_mktdata_mdsservice_fits_to_finance_ind_operational = 1
ORDER BY
cm_mktdata_mdsservice_fits_to_finance_MDSService_fits";
SqlCommand createCommand = new SqlCommand(Query, con);
createCommand.ExecuteNonQuery();
// transfer the results of createCommand to the dataGrid
SqlDataAdapter dataAdapter = new SqlDataAdapter(createCommand);
DataTable dt = new DataTable("vcm_mktdata_mdsservice_fits_to_finance");
dataAdapter.Fill(dt);
dataGrid_ServiceName.ItemsSource = dt.DefaultView;
dataAdapter.Update(dt);
con.Close();
// Enable the Refresh Grid Button
btn_RefreshGrid_ServiceName.IsEnabled = true;
// get DataGrid row count
lbl_dataGrid_RowCount_ServiceName.Content = dataGrid_ServiceName.Items.Count.ToString() + " rows";
//return true;
}
catch (SqlException ex)
{
MessageBox.Show(ex.ToString());
//return false;
}
}
else
{
MessageBox.Show("Connection not established to the SQL Server. " + Environment.NewLine + "The SQL Server may be offline or valid credentials are not yet granted.", "SQL Server Connection Error", MessageBoxButton.OK, MessageBoxImage.Error);
this.Close();
}
this.Cursor = Cursors.Arrow;
}
The DatabaseClass is as follows
class DatabaseClass
{
// Variables
private string _connectionString = "";
public DatabaseClass(string connectionString)
{
_connectionString = connectionString;
}
/// Check to see if Connection can be opened
///
/// Returns True if the connection can be open else it returns False
///
public bool CheckSQLConnection()
{
SqlConnection con = new SqlConnection(_connectionString);
try
{
con.Open();
con.Close();
return true;
}
catch (SqlException ex)
{
return false;
}
}
}
And for the connection string it will look as follows
public static string SQLDataSourceStr = "Data Source=MySQL-DB-DV;Initial Catalog=My_Data;Integrated Security=True";

When is a String not a String

From the "Things that go bump in the database engine" department:
This function returns what looks like a valid value, but the record is not posted (no err msg):
private String GetInterpreterTicketIDSequenceVal()
{
con = new OracleConnection(oradb);
con.Open();
String query = "SELECT TO_CHAR(SYSDATE,'YYYYMMDD-') || LTRIM(TO_CHAR(ABC.SOMETABLEID.NEXTVAL, '000000')) FROM DUAL";
cmd = new OracleCommand(query, con);
cmd.CommandType = CommandType.Text;
//MessageBox.Show(cmd.ExecuteScalar().ToString());
return cmd.ExecuteScalar().ToString();
}
...SEEMS to work (returns a value, and the insertion is (seemingly) made without squawking)... yet, no record is inserted into the database.
This kludgy (sp?) function, OTOH:
private String GetSomeTableIDSequenceVal_Fake()
{
int iYear = DateTime.Now.Year;
int iMonth = DateTime.Now.Month;
int iDay = DateTime.Now.Day;
int iHour = DateTime.Now.Hour;
int iSecond = DateTime.Now.Second;
String sYear = iYear.ToString();
String sMonth = iMonth.ToString();
String sDay = iDay.ToString();
String sHour = iHour.ToString();
String sSecond = iSecond.ToString();
if (iMonth < 10)
{
sMonth = String.Format("0{0}", sMonth);
}
if (iDay < 10)
{
sDay = String.Format("0{0}", sDay);
}
if (iHour < 10)
{
sHour = String.Format("0{0}", sHour);
}
if (iSecond < 10)
{
sSecond = String.Format("0{0}", sSecond);
}
return String.Format("{0}{1}{2}-{3}{4}", sYear, sMonth, sDay, sHour, sSecond);
}
...works fine - the record is inserted into the database (the code that calls these functions follows).
It seems odd that they both return a string, yet one works, and one doesn't... that column doesn't have a constraint on it that is rejecting the value from the former function, so…???
Anyway, here’s the code that calls either of those functions, in context:
try
{
con = new OracleConnection(oradb);
con.Open();
String query = "INSERT INTO ABC.SOMETABLE (TICKETID, TICKETSOURCE, ABOUTSOMEID, CATEGORYID, CONTACTEMAIL) VALUES (:p_TICKETID, :p_TICKETSOURCE, :p_ABOUTSOMEID, :p_CATEGORYID, :p_CONTACTEMAIL)";
cmd = new OracleCommand(query, con);
cmd.CommandType = CommandType.Text;
// Params = TICKETID, TICKETSOURCE, ABOUTSOMEID, CATEGORYID, CONTACTEMAIL
OracleParameter p_TICKETID = new OracleParameter();
p_TICKETID.Direction = ParameterDirection.Input;
p_TICKETID.OracleDbType = OracleDbType.NVarchar2;
p_TICKETID.Size = 20;
// This doesn't allow the record to be inserted...???
//p_TICKETID.Value = GetSomeTableIDSequenceVal();
// ...but when I "fake it" below, the record IS inserted
//p_TICKETID.Value = GetSomeTableIDSequenceVal_Fake(); cmd.Parameters.Add(p_TICKETID);
OracleParameter p_TICKETSOURCE = new OracleParameter();
p_TICKETSOURCE.Direction = ParameterDirection.Input;
p_TICKETSOURCE.OracleDbType = OracleDbType.NVarchar2;
p_TICKETSOURCE.Size = 20;
p_TICKETSOURCE.Value = textBoxTicketSource.Text;
cmd.Parameters.Add(p_TICKETSOURCE);
OracleParameter p_ABOUTSOMEID = new OracleParameter();
p_ABOUTSOMEID.Direction = ParameterDirection.Input;
p_ABOUTSOMEID.OracleDbType = OracleDbType.Int32;
p_ABOUTSOMEID.Value = textBoxAboutSOMEID.Text;
cmd.Parameters.Add(p_ABOUTSOMEID);
OracleParameter p_CATEGORYID = new OracleParameter();
p_CATEGORYID.Direction = ParameterDirection.Input;
p_CATEGORYID.OracleDbType = OracleDbType.Int32;
p_CATEGORYID.Value = textBoxCategoryID.Text;
cmd.Parameters.Add(p_CATEGORYID);
OracleParameter p_CONTACTEMAIL = new OracleParameter();
p_CONTACTEMAIL.Direction = ParameterDirection.Input;
p_CONTACTEMAIL.OracleDbType = OracleDbType.NVarchar2;
p_CONTACTEMAIL.Size = 100;
p_CONTACTEMAIL.Value = textBoxContactEmail.Text;
cmd.Parameters.Add(p_CONTACTEMAIL);
try
{
cmd.ExecuteNonQuery();
}
catch (OracleException ex)
{
MessageBox.Show(ex.Message);
}
MessageBox.Show("Apparent success");
}
finally
{
con.Close();
con.Dispose();
}
Update:
I added Xaction support, and it seems to make no difference whatsoever:
I encased it in a Transaction, and it makes no difference:
OracleTransaction ot;
. . .
try
{
ot = con.BeginTransaction();
cmd.Transaction = ot;
cmd.ExecuteNonQuery();
ot.Commit();
}
catch (Exception ex)
{
ot.Rollback();
}
Update redux:
Luke made a good point about using two simultaneous connections; so, I changed that code to this:
private String GetInterpreterTicketIDSequenceVal()
{
String query = "SELECT TO_CHAR(SYSDATE,'YYYYMMDD-') || LTRIM(TO_CHAR(ABC.SOMETABLEID.NEXTVAL, '000000')) FROM DUAL";
OracleCommand oc = new OracleCommand(query, con);
oc.CommandType = CommandType.Text;
String s = oc.ExecuteScalar().ToString();
try
{
return s;
}
catch (OracleException ex)
{
MessageBox.Show(ex.Message);
return string.Empty;
}
}
...but still no joy in Mudville.
Update redux revisited:
I got it working; thanks everybody for your help and insight.
Actually, it had been working for awhile – my stupid query in Toad was the problem – I forgot that I was adding a slightly different value in new records than what I was querying for … so it looked like the records weren’t being added, but they really were.
tgif!
I tried running your code above and I was only able to reproduce problems with it if the INTERPRETERTICKETID sequence had gone beyond 999999. If you are having problems then there must be something that you are not telling us. For example, how is your table INTERPRETERTICKET defined? What constraints are on it? How is the sequence defined? Are there any triggers on the table?
Is there any need for your GetInterpreterTicketIDSequenceVal() method to use its own connection to the database? Can it not just use the same connection that the rest of your code does?
If your sequence INTERPRETERTICKETID has gone beyond 999999 then the TO_CHAR call will return a string of hashes:
SQL> select ltrim(to_char(999999, '000000')) from dual;
LTRIM(T
-------
999999
SQL> select ltrim(to_char(1000000, '000000')) from dual;
LTRIM(T
-------
#######
I put a PK constraint on the TICKETID column and after running your code twice, I got a constraint violation error.
EDIT:
In response to your comment, it is possible to use a trigger to populate the TICKETID column. You mentioned that your database apparently contains one such trigger, but without seeing how the trigger is defined, it's difficult to know what the problem with it could be.
I added the following trigger, and modified the C# code so that it didn't attempt to insert a value for TICKETID. I ran the C# code a few times and it seemed to work.
CREATE OR REPLACE TRIGGER INTERPRETERTICKETS_BI
BEFORE INSERT ON INTERPRETERTICKETS
FOR EACH ROW
BEGIN
SELECT TO_CHAR(SYSDATE,'YYYYMMDD-') || LTRIM(TO_CHAR(INTERPRETERTICKETID.NEXTVAL, '000000'))
INTO :new.TICKETID
FROM DUAL;
END;
/
the way you setup the parameters seems very strange since your parameter object end up without a name - try changing your code similar to this:
OracleParameter p_TICKETID = new OracleParameter("p_TICKETID", OracleDbType.NVarchar2, ParameterDirection.Input);
p_TICKETID.Size = 20;

Categories

Resources