Actually i am a beginner in database ..
I have written a stored procedure in which I want to get results in c# winform app from two different tables using if else , for instance I have two tables with one column in common that is 'comp_number' .. now I have written a stored procedure which executes on a button click event
ALTER procedure [dbo].[complainVehicle_sp]
as
DECLARE #compno int
if #compno is not null
begin
select compno,compdate,regno,engineno,mcode from dbo.complainVehicle
where compno = #compno
end
else
begin
select compno,recoverydt,recoverytime,statuscode from dbo.complainRecovery
where compno = #compno
end
Now I want that if Compno matches table complainVehicle it shows me the result against this , and if it matches with table complainRecovery it shows me the result against that record else it will display no record ..
here is my c# code
string str = #"Data Source=.;Initial Catalog=----;Integrated Security=False;User ID=sa;Password=----;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;";
SqlConnection cnn = null;
try
{
cnn = new SqlConnection(str);
cnn.Open(); //open the connection
}
catch (SqlException err)
{
Console.WriteLine("Error: " + err.ToString());
}
finally
{
if (cnn != null)
{
cnn.Close();
}
}
if (textBox1.Text.Trim().Length == 0)
{MessageBox.Show("No Record");}
else if (textBox1.Text.Trim().Length > 0)
{
cnn.Open();
SqlCommand cmd2 = new SqlCommand();
cmd2.Connection = cnn;
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandText = "complainVehicle_sp";
cmd2.Parameters.Add("#compno", System.Data.SqlDbType.NVarChar).Value = textBox1.Text.ToString();
cmd2.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter(cmd2);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
cnn.Close();
As I write compno in textbox and click sumbit it shows an error
`An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Procedure complainVehicle_sp has no parameters and arguments were supplied.`
... i would appreciate you all for this help .. thanks in advance guys
In your code you are using DECLARE #compno int, which creates a local variable within the procedure body. The #compno variable is not accessible from outside of the stored procedure context, and it means nothing to the C# code that is invoking the procedure:
cmd2.Parameters.Add(
"#compno",
System.Data.SqlDbType.NVarChar).Value = textBox1.Text.ToString();
So, to address your issue, first, change the stored procedure to accept parameters.
ALTER PROCEDURE [dbo].[complainVehicle_sp]
-- declare a parameter #compono to the procedure
#compno INT
as ...
BEGIN
IF #compno IS NOT NULL
BEGIN
SELECT compno,compdate,regno,engineno,mcode
FROM dbo.complainVehicle
WHERE compno = #compno
END
ELSE
BEGIN
SELECT compno,recoverydt,recoverytime,statuscode
FROM dbo.complainRecovery
WHERE compno = #compno
END
END
Second, you must add the appropriate parameter type in your C# code:
cmd2.Parameters.Add(
"#compno",
System.Data.SqlDbType.Int).Value = int.Parse(textBox1.Text);
Since the parameter is declared as INT in the stored procedure definition, you need to use System.Data.SqlDbType.Int and provide a valid integer value by calling int.Parse(textBox1.Text).
Refer to T-SQL Stored Procedure Syntax for more information on creating stored procedures and parameter options
Firstly, you have to declare your procedure with a parameter, then you probably want to use EXISTS to check each table, something like this;
alter procedure [dbo].[complainVehicle_sp] (#compno int)
as
if (exists (select 1 from dbo.complainVehicle where compno = #compno ) )
begin
select compno,compdate,regno,engineno,mcode from dbo.complainVehicle
where compno = #compno
end
else
if (exists (select 1 from dbo.complainRecovery where compno = #compno ) )
begin
select compno,recoverydt,recoverytime,statuscode from dbo.complainRecovery
where compno = #compno
end
You also need to specify the type of the parameter correctly;
cmd2.Parameters.Add("#compno", System.Data.SqlDbType.Int).Value = textBox1.Text.ToString();
Related
I am executing a SQL Server stored procedure in C#, but both my output parameters are returned blank. But when I run this stored procedure directly in SSMS, then I get values for both parameters. I used same input order no.
Can anyone tell me what's wrong in my code? Thank you
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("wt_find_open_pick_ticket_count", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#input_order_no", order_no);
cmd.Parameters.Add("#status", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.Parameters.Add("#results", SqlDbType.VarChar, 1000).Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteNonQuery();
MessageBox.Show(cmd.Parameters["#status"].Value.ToString());
MessageBox.Show(cmd.Parameters["#results"].Value.ToString());
}
ALTER procedure wt_find_open_pick_ticket_count
#input_order_no varchar(20),
#results varchar(1000) OUTPUT,
#status int OUTPUT
AS
SELECT
status =
CASE
WHEN COUNT(oe_pick_ticket.pick_ticket_no)>0 THEN 0
ELSE 1
END,
results =
CASE
WHEN COUNT(oe_pick_ticket.pick_ticket_no)> 0 THEN 'Message'
ELSE ''
END
FROM oe_pick_ticket with (nolock)
WHERE
oe_pick_ticket.order_no = #input_order_no
AND oe_pick_ticket.invoice_no IS NULL
AND oe_pick_ticket.delete_flag = 'N'
AND oe_pick_ticket.print_date > '2014-01-01'
GROUP BY oe_pick_ticket.order_no
This stored procedure returns a resultset. It does not return output parameters. In order to return output paramters, SP has to change to something like:
select
#paramout1 = val1,
#paramout2 = val2
Notice "#" that is preceding parameter names.
I have a stored procedure called lastID like this:
CREATE PROCEDURE lastID(#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #f VARCHAR(64);
SELECT TOP 1 #f = work_id
FROM workorder
WHERE (RIGHT(work_id,2)) = (RIGHT(Year(getDate()),2))
ORDER BY work_id DESC;
IF(#f IS NULL)
BEGIN
SET #f = 'No work orders';
SET #id = #f;
RETURN #id;
END
ELSE
BEGIN
SET #id = #f;
RETURN #id;
END
END
This stored procedure returns the last id from the table workorder, now I'm trying to execute this procedure in C#, this is the code:
private void lastWorkId()
{
String strConnString = "Server=.\\SQLEXPRESS;Database=recalls;Integrated Security=true";
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "lastID";
cmd.Parameters.Add("#id", SqlDbType.VarChar, 64).Direction = ParameterDirection.Output;
cmd.Connection = con;
try
{
con.Open();
cmd.ExecuteNonQuery();
String id = cmd.Parameters["#id"].Value.ToString();
lastid.Text = id.ToString(); //Putting the return value into a label
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
}
I don't know what are wrong with my code, because an exception is displayed, and this says
Conversion failed when converting the varchar value ' OT- 003-16 ' to data type int
I was wrong about my first answer, here is the updated answer:
Your stored procedure is setup with an OUTPUT parameter of type VARCHAR(64).
Within your proc you have a couple of RETURN #id; statements, which is actually returning a VARCHAR(64). You only need to set your OUTPUT variable within the stored procedure. The RETURN statement expects an integer expression. Here's the updated fixed sproc using OUTPUT appropriately:
ALTER PROCEDURE [dbo].[lastID](#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #f VARCHAR(64);
SELECT TOP 1 #f = work_id FROM workorder WHERE (RIGHT(work_id,2)) = (RIGHT(Year(getDate()),2)) ORDER BY work_id DESC;
IF(#f IS NULL)
BEGIN
SET #f = 'No work orders';
SET #id = #f;
END
ELSE
BEGIN
SET #id = #f;
END
END
Error is basically should get fixed by cast
((RIGHT(work_id,2)) as int)
But code can be further condensed and improved.
CREATE PROCEDURE lastID(#id varchar(64) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
SELECT TOP 1 #id = isnull(work_id , 'No work orders') FROM workorder WHERE cast ((RIGHT(work_id,2)) as int)= (RIGHT(Year(getDate()),2)) ORDER BY work_id DESC;
RETURN #id;
END
I'm trying to call the below stored procedure but I am unsure on what to pass through one of the parameters (#UnsubscribeTypes) I've tried passing in a list but got a compile error. I'm using c#, Visual Studio 2010, web forms. Any ideas on what I should pass in when calling the stored procedure in my c# code (ado.net)?
Here is my stored procedure:
ALTER PROCEDURE [czone].[SetAccountEmailPreference]
(
#EmailAddress VARCHAR(255),
#UnsubscribeTypes dbo.ListOfIDs READONLY,
#SentEmailID INT = NULL
)
AS
SET NOCOUNT ON;
EXEC dbo.LogObjectExecution ##PROCID;
DECLARE #UnsubscribeID INT = (SELECT TOP 1 UnsubscribeID
FROM Email.dbo.Unsubscribe
WHERE EmailAddress = #EmailAddress
ORDER BY UnsubscribeID DESC);
-- Unsubscribe
IF ((SELECT COUNT(*) FROM #UnsubscribeTypes) > 0)
BEGIN
IF(#UnsubscribeID IS NULL)
BEGIN
-- ADD UNSUBSCRIBE
INSERT INTO Email.dbo.Unsubscribe (EmailAddress, CreatedDate)
VALUES (#EmailAddress, CURRENT_TIMESTAMP)
SET #UnsubscribeID = ##IDENTITY;
END
-- Remove current mappings
DELETE FROM Email.dbo.UnsubscribeTypeMapping
WHERE UnsubscribeFK = #UnsubscribeID;
-- Add new mappings
INSERT INTO Email.dbo.UnsubscribeTypeMapping (UnsubscribeFK, UnsubscribeTypeFK, SentEmailFK)
SELECT
#UnsubscribeID, ID, #SentEmailID
FROM
#UnsubscribeTypes;
END
-- Subscribe
ELSE IF (#UnsubscribeID IS NOT NULL)
BEGIN
DELETE FROM Email.dbo.Unsubscribe
WHERE UnsubscribeID = #UnsubscribeID;
END
dbo.ListOfIDs is a table type. First, find out the type in your database, then check columns. generate a datatable with rows containing the UnsubscribeTypeFK ids.
The ADO.net code (not compiled)
Creating table
DataTable dt = new DataTable("Items");
dt.Columns.Add("ID", typeof(int));
dt.Rows.Add(4);
Calling proc
con = new SqlConnection(conStr);
con.Open();
using (con) {
// Configure the SqlCommand and SqlParameter.
SqlCommand sqlCmd = new SqlCommand("czone.SetAccountEmailPreference", con);
sqlCmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvpParam = sqlCmd.Parameters.AddWithValue("#UnsubscribeTypes", _dt); // TVP
tvpParam.SqlDbType = SqlDbType.Structured; //tells ADO.NET we are passing TVP
//pass other parameters
sqlCmd.ExecuteNonQuery();
}
con.Close();
You will find more about Table-Valued parameters here
I am creating a web application using ASP.net C#. I have a booking form and I need to insert data into a table using a Stored Procedure. The table has several columns, out of which second column is a computed column. The Stored Procedure is set up to insert the data and fetch the value from the second column after insert. Below is the code for Stored Procedure:
Create Procedure sp_InsertCashPooja
#FirstName varchar(100),
#LastName varchar(100),
#TelNo bigint,
#Star char(50),
#Rasi char(50),
#Gothram char(50),
#PDMID int,
#PayMode bit,
#PujaName char(50),
#DonateAmt decimal(19,2),
#RcptNo varchar(25) output
as
Begin
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION
if #PujaName != 'DONATION'
Begin
INSERT INTO PoojaDetails (FirstName, LastName, TelNo, Star, Rasi, Gothram, PoojaDietyMasterID, PayMode) values (#FirstName,#LastName,#TelNo,#Star,#Rasi,#Gothram,#PDMID,#PayMode)
End
if #PujaName = 'DONATION'
Begin
DECLARE #isDonate int = 0;
INSERT INTO PoojaDetails (FirstName, LastName, TelNo, Star, Rasi, Gothram, PoojaDietyMasterID, PayMode, isDonate, DonateAmount) values (#FirstName,#LastName,#TelNo,#Star,#Rasi,#Gothram,#PDMID,#PayMode, #isDonate, #DonateAmt)
End
Select #RcptNo = max(ReceiptNo) from PoojaDetails
Return #RcptNo
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
ROLLBACK TRANSACTION
END CATCH
SET NOCOUNT OFF;
End
I would like to insert data on the click of a button: I was able to figure out the below code....
protected void btnSave_Click(object sender, EventArgs e)
{
frmFirstName = txtFirstName.Text.Trim().ToUpper();
frmLastName = txtLastName.Text.Trim().ToUpper();
frmPhoneNo = Convert.ToInt32(txtPhoneNo.Text.Trim());
frmNakshatra = Convert.ToString(cmbNakshatra.SelectedItem).Trim();
frmRasi = Convert.ToString(cmbRasi.SelectedItem).Trim();
frmGothram = Convert.ToString(cmbGothram.SelectedItem).Trim();
frmPujaName = Convert.ToString(cmbPujaName.SelectedItem).Trim();
using (SqlConnection connection = new SqlConnection())
{
if (frmPayMode == "Cash")
{
if (frmPujaName == "DONATION")
{
SqlDataAdapter CashAdapter = new SqlDataAdapter();
CashAdapter.InsertCommand = new SqlCommand("sp_InsertCashPooja", connection);
CashAdapter.InsertCommand.CommandType = CommandType.StoredProcedure;
Please help.... I want to capture the returning RcptNo and later intend to call another ASPX page and pass the value using a Query String.
Thanks
Use simple SqlCommand for calling your SP
connection.Open();
var cmd = new SqlCommand("sp_InsertCashPooja", connection);
cmd.Parameters.AddWithValue("FirstName", frmFirstName);
// Add all the others parameters in same way
var id = (int)cmd.ExecuteScalar();
connection.Close();
Change the return variable to:
Select #RcptNo = SCOPE_IDENTITY()
It will return the identity number created for the inserted record within this procedure.
use sql parameter..
connection = ConfigurationManager.AppSettings["mycon"];
SqlParameter[] para = new SqlParameter[2];
para[0] = new SqlParameter("#stored procedure column name", string name);
para[1] = new SqlParameter("#stored procedure column name", string name);
This is a strange one. I have a Dev SQL Server which has the stored proc on it, and the same stored proc when used with the same code on the UAT DB causes it to delete itself!
Has anyone heard of this behaviour?
SQL Code:
-- Check if user is registered with the system
IF OBJECT_ID('dbo.sp_is_valid_user') IS NOT NULL
BEGIN
DROP PROCEDURE dbo.sp_is_valid_user
IF OBJECT_ID('dbo.sp_is_valid_user') IS NOT NULL
PRINT '<<< FAILED DROPPING PROCEDURE dbo.sp_is_valid_user >>>'
ELSE
PRINT '<<< DROPPED PROCEDURE dbo.sp_is_valid_user >>>'
END
go
create procedure dbo.sp_is_valid_user
#username as varchar(20),
#isvalid as int OUTPUT
AS
BEGIN
declare #tmpuser as varchar(20)
select #tmpuser = username from CPUserData where username = #username
if #tmpuser = #username
BEGIN
select #isvalid = 1
END
else
BEGIN
select #isvalid = 0
END
END
GO
Usage example
DECLARE #isvalid int
exec dbo.sp_is_valid_user 'username', #isvalid OUTPUT
SELECT valid = #isvalid
The usage example work all day... when I access it via C# it deletes itself in the UAT SQL DB but not the Dev one!!
C# Code:
public bool IsValidUser(string sUsername, ref string sErrMsg)
{
string sDBConn = ConfigurationSettings.AppSettings["StoredProcDBConnection"];
SqlCommand sqlcmd = new SqlCommand();
SqlDataAdapter sqlAdapter = new SqlDataAdapter();
try
{
SqlConnection conn = new SqlConnection(sDBConn);
sqlcmd.Connection = conn;
conn.Open();
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.CommandText = "sp_is_valid_user";
// params to pass in
sqlcmd.Parameters.AddWithValue("#username", sUsername);
// param for checking success passed back out
sqlcmd.Parameters.Add("#isvalid", SqlDbType.Int);
sqlcmd.Parameters["#isvalid"].Direction = ParameterDirection.Output;
sqlcmd.ExecuteNonQuery();
int nIsValid = (int)sqlcmd.Parameters["#isvalid"].Value;
if (nIsValid == 1)
{
conn.Close();
sErrMsg = "User Valid";
return true;
}
else
{
conn.Close();
sErrMsg = "Username : " + sUsername + " not found.";
return false;
}
}
catch (Exception e)
{
sErrMsg = "Error :" + e.Source + " msg: " + e.Message;
return false;
}
}
Ok, I have found the answer ... simple when you know how!
I saw this link here :
Disappearing Stored Procedure
Disappearing Stored Procedure
So from the best answer in that I ran :
select syo.name
from syscomments syc
join sysobjects syo on
syo.id = syc.id
where syc.[text] like '%DROP PROC%'
This gave me one of my OTHER stored procs back... sp_is_user_admin, which didn't seem right so I had a quick look ...
create procedure dbo.sp_is_user_admin
#username as varchar(20),
#isadmin as int OUTPUT
AS
BEGIN
declare #profile as varchar(20)
select #profile = profile from CPUserData where username = #username
if #profile = 'admin'
BEGIN
select #isadmin = 1
END
else
BEGIN
select #isadmin = 0
END
END
--*********************************************************************************
-- Check if user is registered with the system
IF OBJECT_ID('dbo.sp_is_valid_user') IS NOT NULL
BEGIN
DROP PROCEDURE dbo.sp_is_valid_user
IF OBJECT_ID('dbo.sp_is_valid_user') IS NOT NULL
PRINT '<<< FAILED DROPPING PROCEDURE dbo.sp_is_valid_user >>>'
ELSE
PRINT '<<< DROPPED PROCEDURE dbo.sp_is_valid_user >>>'
END
Doh!!! There is the blighter... in the C# what happens is that if the user is valid I also choose what to let them see based on if they are admin or not and calling that was blitzing the sp_is_valid_user proc. Nasty side effect!
// check the user is entitled to use the system at all
if (usrData.IsValidUser(sCurrentUserName, ref sErrMsg))
{
// if the user is admin then let them spoof and edit their own data
if (usrData.UserIsAdmin(sCurrentUserName, ref sErrMsg))
{
chkSpoof.Visible = true;
grdvwUserDataFromDB.Visible = true;
}
}
else
{
// redirect them away
Response.Redirect("UserNotRegistered.aspx");
return;
}
I hope this helps someone else out!
PS: DB Artisan is nasty and if I had the full fat SQL Server available in my Development toolkit then I guess I could have used the profiler to see this being called. ;P I can't install SQL Server 2008 as I don't have the right SP / updates to Visual Studio I think and IT here can't sort it out, annoying!!