I have been working on creating the Web API that accepts the input parameter and calls a Stored Procedure passing the input parameter we received that insert/updates the Account Table in the Database. Now that is perfectly , but my API also need to select the record which was updated/inserted and return them as response
public class ProjectNameCreationController : ApiController
{
[HttpGet]
public HttpResponseMessage Get(string Account)
{
if (string.IsNullOrEmpty(Account))
{
return Request.CreateResponse(new { error = "Input parameters cannot be Empty or NULL" });
}
string strcon = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
SqlConnection DbConnection = new SqlConnection(strcon);
DbConnection.Open();
SqlCommand command = new SqlCommand("[dbo].[usp_InserUpadte]", DbConnection);
command.CommandType = CommandType.StoredProcedure;
//create type table
DataTable table = new DataTable();
table.Columns.Add("AccountID", typeof(string));
table.Rows.Add(Account);
SqlParameter parameter = command.Parameters.AddWithValue("#account_TT", table);
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "account_TT";
command.ExecuteNonQuery();
Now I am not sure if we will able to select the record that was now insert/updated as part of the Stored Procedure or will I have to create a Query seperately like below
string strQuery = "select AccountID,CounterSeq from Account where AccountID = #accountID ";
var cmd = new SqlCommand(strQuery);
cmd.Parameters.AddWithValue("#accountID",Account);
Because I will have to Return the response as AccountID-CounterSeq (Eg: IT-1) when the API is called like http://localhost/api/ProjectNameCreation?Account=IT. How can I deal with this. Any help is greatly appreciated
You have to change your procedure as below it will return a record of last inserted or updated.
**--for insert**
IF #StatementType = 'Insert'
BEGIN
insert into Account (first_name,last_name,salary,city) values( #first_name, #last_name, #salary, #city)
--below line to return last inserted record
select * from Account where accountid= SCOPE_IDENTITY()
END
**--for Update**
IF #StatementType = 'Update'
BEGIN
UPDATE Account SET
First_name = #first_name, last_name = #last_name, salary = #salary,
city = #city
WHERE accountid= #accountid
--below line to return last Updated record
select * from account where accountid = #accountid
Related
I'm attempting to call my sql stored procedure which takes RaceDate as an input and returns Location as an OUTPUT. I'm not sure how to call my code in ASP.NET, this is what I have thus far.
DateTime RaceDate = Calendar1.SelectedDate;
// string RaceDate = TxtBoxCalendar.Text;
TxtBoxCalendar.ReadOnly = true;
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ToString();
con.Open();
SqlCommand Command = new SqlCommand();
Command.CommandType = System.Data.CommandType.StoredProcedure;
Command.CommandText = "CheckRaceCalendarDates";
Command.Parameters.Add("#RaceDate", SqlDbType.DateTime, RaceDate);
Command.Parameters.Add("#Location", SqlDbType.String).Direction = ParameterDirection.Output;
Command.Parameters.Add("#Location",SqlDbType.String).Direction = ParameterDirection.Output;
Command.ExecuteNonQuery();
con.Close();
I think i may also run into a problem with datatypes. RaceDate is a date the user clicks through a calendar and has to be converted to a string however the SQL parameter RaceDate is of type date.
CREATE PROCEDURE [dbo].[CheckRaceCalendarDates]
#RaceDates DATE,
#Location NVARCHAR(50) OUTPUT
AS
IF EXISTS
(
SELECT
RaceCalendar.RaceDates,
Locations.LocationName
FROM
Locations
INNER JOIN RaceCalendar ON locations.LocationId = RaceCalendar.LocationId
WHERE
RaceCalendar.RaceDates = #RaceDates
)
BEGIN
SELECT
#Location = Locations.LocationName
FROM
Locations
INNER JOIN RaceCalendar ON locations.LocationId = RaceCalendar.LocationId
WHERE
RaceCalendar.RaceDates = #RaceDates
END
Your problem about using parameter name ; you have used #RaceDates on stored procedure but you try to use #RaceDate on code.. They should be same.
Also, you need to add second parameter to your code like this ;
Command.Parameters.Add("#Location",SqlDbType.String).Direction = ParameterDirection.Output;
And after cmd.ExeCuteNonQuery();
string location = Command.Parameters["#Location"].Value.ToString();
I am creating a Web API that accepts two input parameter called ACC. Created a stored procedure to insert or update the Account table in the SQL server. Account table has just two fields AccountID nvarchar(50) (primaryKey) and Cnt int
CREATE PROCEDURE [dbo].[usp_InserUpadte]
#Account_TT AS Account_TT READONLY
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
MERGE dbo.[Account] prj
USING #Account_TT tt
ON prj.AccountID = tt.AccountID
WHEN MATCHED THEN UPDATE SET prj.Cnt = prj.Cnt+1
WHEN NOT MATCHED THEN INSERT (AccountID,Cnt)
VALUES (tt.AccountID, 1);
COMMIT TRANSACTION;
Now I tried to connect to the SQL server not sure how to how would I call the stored procedure into the ASP.NET Web API application and pass the Account ID in it to create or updadte the table
namespace WebService.Controllers
{
public class CreationController : ApiController
{
[HttpGet]
public HttpResponseMessage Get(string ACC)
{
string strcon = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
SqlConnection DbConnection = new SqlConnection(strcon);
I know we can call the query directly like
var strQuery = "SELECT * from ACCOUNT where ACC = :ACC"
But dont know how to call the above stored procedure and pass the Account Value. Any help is greatly appreciated.
Here is the complete working example.
Please have a look on it.
string strcon = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
SqlConnection DbConnection = new SqlConnection(strcon);
DbConnection.Open();
SqlCommand command = new SqlCommand("[dbo].[usp_InserUpadte]", DbConnection);
command.CommandType = CommandType.StoredProcedure;
//create type table
DataTable table = new DataTable();
table.Columns.Add("AccountID", typeof(string));
table.Rows.Add(ACC);
SqlParameter parameter = command.Parameters.AddWithValue("#Account_TT", table);
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "Account_TT";
command.ExecuteNonQuery();
DbConnection.Close();
To call a stored procedure you need to use a SqlCommand something like this:
string strcon = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
using (var connection = new SqlConnection(strcon)) {
using (var command = new SqlCommand("usp_InserUpadte", connection)) {
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#Account_TT ", SqlDbType.NVarChar).Value = ACC;
command.Open();
var reader = command.ExecuteReader();
// Handle return data here
}
}
I have built a website with a MySQL back-end with php as the server language, now i shall build the same site in asp.net
The following procedure is define in the MySQL database:
DELIMITER //
CREATE PROCEDURE Login(
IN Username VARCHAR(16),
IN UserPassword VARCHAR(16),
OUT UID int,
OUT SL INT,
OUT SP VARCHAR(8),
OUT MA BOOL) -- missing admin entry
BEGIN
DECLARE adminID INT DEFAULT -1;
DECLARE lastTimeout DATETIME DEFAULT NULL;
SET UID = -1;
SELECT ID, SecurityLevel, LoginTimeout INTO UID, SL, lastTimeout
FROM User
WHERE User.UserName = Username and User.Password = UserPassword;
IF NOW() > lastTimeout OR lastTimeOut IS NULL THEN
IF lastTimeOut IS NOT NULL THEN
INSERT INTO UserLog (UserID, Date, Action) VALUES (UID, NOW(), 'TIMEOUT');
END IF;
SELECT ID, Password INTO SL, SP
FROM SecurityLevels
WHERE ID = SL;
SELECT UserID INTO adminID
FROM Admin
WHERE UserID = UID;
IF adminID = -1 AND SL = 4 THEN SET MA = TRUE;
ELSE SET MA = FALSE;
END IF;
IF UID != -1 THEN
INSERT INTO UserLog (UserID, Date, Action) VALUES (UID, NOW(), 'LOGIN');
UPDATE User SET User.LoginTimeOut = DATE_ADD(NOW(), INTERVAL 1 HOUR) WHERE User.ID = UID;
END IF;
ELSE
SET UID = -1;
END IF;
END //
DELIMITER ;
The user I use is:
CREATE USER 'LOGIN'#'%' IDENTIFIED BY '6Jd8kKi0';
GRANT execute ON procedure b09xxxxx.Login TO 'LOGIN'#'%';
Now, in php I do it like this, and it works like a charm:
$pdo = new PDO('mysql:dbname=b09xxxxx;host=wwwlab.xxx.xxx.se', 'LOGIN', '6Jd8kKi0');
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$userID = 0;
$securityLevel = 0;
$securityPassword = "";
//$sql = "SELECT UserName, ID, SecurityLevel FROM User WHERE UserName = '" . $_POST['username'] . "' and Password = '" . $_POST['password'] . "';";
$sql = "CALL Login(:USERNAME, :PASSWORD, #UID, #SL, #SP, #MA);";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':USERNAME', $_POST['username']);
$stmt->bindParam(':PASSWORD', $_POST['password']);
$stmt->execute();
//$q = $pdo->query($sql) or die("ERROR:DB");
$sql = "SELECT #UID, #SL, #SP, #MA;";
$q = $pdo->query($sql) or die("ERROR:DB");
$r = $q->fetch(PDO::FETCH_ASSOC);
But this asp.net (C#) version does not work:
string connectionString = "Server=wwwlab.xxx.xxx.se; Database=b09xxxxx; User ID=LOGIN; Password=6Jd8kKi0; Pooling=false;";
MySqlConnection dbcon = new MySqlConnection(connectionString);
dbcon.Open();
//string query = "CALL Login(:USERNAME, :PASSWORD, #UID, #SL, #SP, #MA);";
//Now changed to this thanks to John Woo
string query = "Login";
MySqlCommand sqlCmd = new MySqlCommand(query, dbcon);
sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue(":USERNAME", loginUsername.Text);
sqlCmd.Parameters[":USERNAME"].Direction = ParameterDirection.Input;
sqlCmd.Parameters.AddWithValue(":PASSWORD", loginPassword.Text);
sqlCmd.Parameters[":PASSWORD"].Direction = ParameterDirection.Input;
sqlCmd.Parameters.Add(new MySqlParameter("#UID", MySqlDbType.Int64));
sqlCmd.Parameters["#UID"].Direction = ParameterDirection.Output;
sqlCmd.Parameters.Add(new MySqlParameter("#SL", MySqlDbType.Int64));
sqlCmd.Parameters["#SL"].Direction = ParameterDirection.Output;
sqlCmd.Parameters.Add(new MySqlParameter("#SP", MySqlDbType.String));
sqlCmd.Parameters["#SP"].Direction = ParameterDirection.Output;
sqlCmd.Parameters.Add(new MySqlParameter("#MA", MySqlDbType.Byte));
sqlCmd.Parameters["#MA"].Direction = ParameterDirection.Output;
sqlCmd.ExecuteNonQuery();
MySqlDataAdapter adapter = new MySqlDataAdapter("SELECT #UID, #SL, #SP, #MA;", dbcon);
DataSet ds = new DataSet();
adapter.Fill(ds, "result");
CustomerGrid.DataSource = ds.Tables["result"];
CustomerGrid.DataBind();
dbcon.Close();http://stackoverflow.com/editing-help
I get the following error:
Procedure or function 'CALL Login(:USERNAME, :PASSWORD, #UID, #SL, #SP, #MA)' cannot be found in database 'b09xxxxx'.
Edit: now this is the new problem: SELECT command denied to user 'LOGIN'#'193.11.99.23' for table 'proc'
I reckon that the error is being generated when calling the .Fill method.
Change the below code;
MySqlDataAdapter adapter = new MySqlDataAdapter("SELECT #UID, #SL, #SP, #MA;", dbcon);
DataSet ds = new DataSet();
adapter.Fill(ds, "result");
CustomerGrid.DataSource = ds.Tables["result"];
With;
DataTable table = new DataTable();
table.Columns.Add("UID", typeof(int));
table.Columns.Add("SL", typeof(int));
table.Columns.Add("SP", typeof(string));
table.Columns.Add("MA", typeof(boolean));
table.Rows.Add(sqlCmd.Parameters["#UID"].Value, sqlCmd.Parameters["#SL"].Value, sqlCmd.Parameters["#SP"].Value, sqlCmd.Parameters["#MA"].Value);
CustomerGrid.DataSource = table
I have a stored procedure on my server that inserts some parameters and returns the ID that was inserted. I am writing a form to do this easily but I cannot seem to get the parameter which is passed back.
To save you doing a whole bunch of possibly pointless reading, it's probably better to just pay attention to my C# code and let me know what I need to do in order to pass parameters and get one in return.
C# Default.aspx
connection = new SqlConnection(ConfigurationManager.AppSettings["ConnectionInfo"]);
sql = "aStoredProc";
command = new SqlCommand(sql, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameter.Add(new SqlParameter("#FirstName", SqlDbType.VarChar)).Value = sFirstname;
command.Parameter.Add(new SqlParameter("#SurName", SqlDbType.VarChar)).Value = sSurname;
connection.Open();
int ID = command.ExecuteNonQuery();
connection.Close();
SQL aStoredProc
IF EXISTS(SELECT * FROM aTable WHERE ID = #ID)
-- User exists, update details
BEGIN
BEGIN TRAN
UPDATE aTable
SET
FirstName = #FirstName,
SurName = #SurName,
LastUpdate = GetDate()
WHERE ID = #ID
IF (##Error != 0)
ROLLBACK TRAN
ELSE
COMMIT TRAN
END
ELSE
-- New user
BEGIN
BEGIN TRAN
INSERT aTable (
FirstName,
SurName,
GetDate()
)
VALUES (
#FirstName,
#SurName,
#LastUpdate
)
SELECT #ID = ##IDENTITY
IF (##Error != 0)
ROLLBACK TRAN
ELSE
COMMIT TRAN
END
The parameter #ID is listed in the stored proc as:
#ID (int, Input/Output, No default)
and proc has 'Return integer'. This used to work fine with a VBA solution prior to a SQL Server 2005 upgrade.
Thanks in advance.
connection = new SqlConnection(ConfigurationManager.AppSettings["ConnectionInfo"]);
sql = "aStoredProc";
command = new SqlCommand(sql, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameter.Add(new SqlParameter("#FirstName", SqlDbType.VarChar)).Value = sFirstname;
command.Parameter.Add(new SqlParameter("#SurName", SqlDbType.VarChar)).Value = sSurname;
command.Parameter.Add(new SqlParameter("#SurName", SqlDbType.VarChar)).Value = sSurname;
SqlParameter ParamId = cmd.Parameters.Add( "#Id", SqlDbType.Int);
ParamId.Direction = ParameterDirection.InputOutput;
command.Parameter.Add(ParamId);
connection.Open();
command.ExecuteNonQuery();
int ID = ParamId.Value;
connection.Close();
you have to add output paramter in Parameter collection.
Read Value like above.
You have an error in your SQL, it should look like this:
INSERT aTable (FirstName,SurName,LastUpdate)
VALUES (#FirstName, #SurName, GetDate() )
Not like this:
INSERT aTable (
FirstName,
SurName,
GetDate()
)
VALUES (
#FirstName,
#SurName,
#LastUpdate
)
I m creating new user registration moduleand for that i wrote following stored proc.
PROCEDURE [dbo].[addNewUser]
-- Add the parameters for the stored procedure here
#usertype VarChar(10),
#useremail VarChar(70),
#userpass VarChar(20),
#fullname VarChar(70),
#city VarChar(70),
#state Int,
#allowAlerts Bit,
#allowLetter Bit,
#aboutMe NVARCHAR(160)
As
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if ((select count(user_info._id) from user_info where useremail like #useremail) = 0)
BEGIN
Insert Into user_info
(usertype,useremail,userpass,fullname,city,[state],allowAlerts,allowLetters,aboutMe)
Values
(
#usertype,
#useremail,
#userpass ,
#fullname,
#city,
#state,
#allowAlerts,
#allowLetter,
#aboutMe
)
Select ##IDENTITY as NewID
END
Else
BEGIN
Print '-1'
END
And following is the simple ASP.net C# Code that I try to use
public int registerNewUser(string usertype, string useremail, string userpass, string fullname, string city, string state, string allowAlerts, string allowLetter, string aboutMe)
{
con = new SqlConnection(connectionString);
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "addBlogEntry";
cmd.Parameters.Add("#usertype", SqlDbType.VarChar).Value = usertype;
cmd.Parameters.Add("#useremail", SqlDbType.VarChar).Value = useremail;
cmd.Parameters.Add("#userpass", SqlDbType.VarChar).Value = userpass;
cmd.Parameters.Add("#fullname", SqlDbType.VarChar).Value = fullname;
cmd.Parameters.Add("#city", SqlDbType.VarChar).Value = city;
cmd.Parameters.Add("#state", SqlDbType.VarChar).Value = Convert.ToInt16(state);
cmd.Parameters.Add("#allowAlerts", SqlDbType.VarChar).Value = Convert.ToInt16(allowAlerts);
cmd.Parameters.Add("#allowLetter", SqlDbType.VarChar).Value = Convert.ToInt16(allowLetter);
cmd.Parameters.Add("#aboutMe", SqlDbType.VarChar).Value = aboutMe;
try
{
if (con.State != ConnectionState.Open)
con.Open();
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
// some code to be written here so that i can return userID(success) or -1(if that username is already registered)
return 0;
}
catch (Exception Ex)
{
con.Close();
con.Dispose();
return 0;
}
}
Through my C# code i want to return either auto generated userId which my stored procedures returns to me or if user alrady exists than i want to return -1
Please tell how to do this?
Thanks in advance :)
Yes, you can use ExecuteScalar() and change
Print '-1'
into
Select -1 as NewID
First of all, you should use SELECT SCOPE_IDENTITY() inside your stored proc to retrieve the new ID value (##IDENTITY can return false results).
And yes, if you want to get the result back, you need to call either .ExecuteScalar() or .ExecuteReader() and then read that value back.
And while you're at it - I'd also recommend putting your SqlConnection and SqlCommand objects into using blocks - so instead of your code, use this:
using(con = new SqlConnection(connectionString))
using(cmd = new SqlCommand(con))
{
..... // put the rest of your code here
}
If you want to create an output parameter for your stored proc, and set it to the new key you can access it that way. ExecuteNonQuery will return the number of rows affected, so that can be used as well. Something like this:
cmd.Parameters.Add("#uniquID", SqlDbType.Int).Direction = ParameterDirection.Output;
// Your other code...
var result = cmd.ExecuteNonQuery();
// Your other code...
return (result == 1) ? (int)cmd.Parameters["#uniquID"].Value : -1;