I have the following code to be executed and I want to get the value of #synchronization_version from c#. Does any one know how this could be handled?
DECLARE #synchronization_version BIGINT
SET #synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();
The most direct way is to use SqlCommand.ExecuteScalar. See this article: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar(v=vs.110).aspx .
Your SQL query would look like this:
SELECT Convert(BigInt,CHANGE_TRACKING_CURRENT_VERSION());
I modified the MSDN code as follows. This should work:
public static Int64 GetSynchronizationVersion(string connString)
{
Int64 synchronizationVersion = 0;
string sql =
"SELECT Convert(BigInt,CHANGE_TRACKING_CURRENT_VERSION());";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
//This query has no parameters.
try
{
conn.Open();
synchronizationVersion = (Int64)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return synchronizationVersion;
}
This operation is called ExecuteScalar because it returns a single value (a scalar) rather than a set of rows.
Wrap it in a procedure like
create procedure Sp_getdata
as
begin
DECLARE #synchronization_version BIGINT OUTPUT
SET #synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();
SELECT #synchronization_version;
end
Call the procedure from C#
SqlParameter outData = new SqlParameter("#synchronization_version", SqlDbType.BIGINT){ Direction = ParameterDirection.Output };
cmd.ExecuteScalar();
Then just read the value of output parameter
long result = outData.Value;
Related
I am populating a text box with the returned value of a function, but it doesn't work if I run the sql code inside the function. I can remove the sql related code and it works. so i'm stumped.
And by "doesn't work" i mean that the text box never gets populated with anything. it remains blank.
thanks
public string CreateResident()
{
string result = "hmm";
SqlConnection sqlConnection = new SqlConnection("Server=DELLXPS\\SQLEXPRESS; Initial Catalog=Warren_SEINDATASYSTEMS; Integrated Security=true;");
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "INSERT INTO [dbo].[NewUsers]([ResidentAccountNumber],[ResidentName],[ResidentAddress],[NumberOfVisitors],[TempPass],[Role])VALUES(#ResidentAccountNumber,#ResidentName,#ResidentAddress,#NumberOfVisitors,(select cast((Abs(Checksum(NewId()))%10) as varchar(1)) + char(ascii('a')+(Abs(Checksum(NewId()))%25)) + char(ascii('A')+(Abs(Checksum(NewId()))%25)) + left(newid(),5)),'resident')";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
SqlParameter ResidentAccountNumber = new SqlParameter();
ResidentAccountNumber.ParameterName = "#ResidentAccountNumber";
ResidentAccountNumber.Value = txtboxResidenetAccountNumber.Text.Trim();
cmd.Parameters.Add(ResidentAccountNumber);
SqlParameter ResidentName = new SqlParameter();
ResidentName.ParameterName = "#ResidentName";
ResidentName.Value = txtboxResidentName.Text.Trim();
cmd.Parameters.Add(ResidentName);
SqlParameter ResidentAddress = new SqlParameter();
ResidentAddress.ParameterName = "#ResidentAddress";
ResidentAddress.Value = txtboxResidentAddress.Text.Trim();
cmd.Parameters.Add(ResidentAddress);
SqlParameter NumberOfVisitors = new SqlParameter();
NumberOfVisitors.ParameterName = "#NumberofVisitors";
NumberOfVisitors.Value = txtboxNumberOfVisitors.Text.Trim();
cmd.Parameters.Add(NumberOfVisitors);
try
{
sqlConnection.Open();
result = (string)cmd.ExecuteScalar();
sqlConnection.Close();
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
protected void btnCreateResident_Click(object sender, EventArgs e)
{
txtboxTempPassword.Text = CreateResident();
}
Your SQL is wrong and you have a lot of problems but I want to show you a way to make your code more readable. Format it like this:
cmd.CommandText = #"INSERT INTO [dbo].[NewUsers] ([ResidentAccountNumber],[ResidentName],[ResidentAddress], NumberOfVisitors],[TempPass], Role])
VALUES(
#ResidentAccountNumber,
#ResidentName,
#ResidentAddress,
#NumberOfVisitors,
(select cast((Abs(Checksum(NewId()))%10) as varchar(1)) + char(ascii('a')+(Abs(Checksum(NewId()))%25)) + char(ascii('A')+(Abs(Checksum(NewId()))%25)) + left(newid(),5)),
'resident')";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
We know that a select in a VALUES constructor is not legal so that is one problem.
Also having a SELECT without a from seems strange -- did you copy your code correctly?
You are using ExecuteScalar -- do you know what that does? It shouldn't include a query that includes INSERT query.
I'm guessing you probably want a stored procedure.
I would suggest do not write query in C# code, you must use Stored Procedure for the same purpose.
If you want your query to return some id, primary key or some value then you must write query for that after your insert query.
you can use the following keywords in your select query,if you want to return id from table.
SCOPE_IDENTITY returns the last IDENTITY value inserted into an IDENTITY column in the same scope.
IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
##IDENTITY returns the last identity value generated for any table in the current session, across all scopes.
If you want to return only one record then use ExecuteScalar else you can use ExecuteReader.
If your only purpose is to insert data into the table then you should use ExecuteNonQuery.
With the help of comments I went with ExecuteReader instead of the ExecuteScaler. And changed the statement to return a value
INSERT INTO [table] ([fields]) OUTPUT Inserted.MyColumn VALUES(values)
C# Code:
reader = cmd.ExecuteReader();
try
{
while (reader.Read())
{
result = reader[0].ToString();
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
I've spent about 7 hours trying to figure this out by trial and error. All the online examples I have seen either don't work, or dont apply, or only show half of what Im looking for.
Here is what I'm asking for:
1. An example of a simple stored procedure in MYSQL using one IN parameter and one OUT parameter.
2. An example of a FUNCTIONING (really important, cause online examples havent worked sometimes...) call from Visual Studio, using C#. Either a text call or stored procedure command type work.
3. AddWithValue has been deprecated.
4. I would love to see the out parameter actually work.
If this is impossible with MYSQL and visual studio, that would be nice to know as well.
MYSQL documentation is not thorough enough for this particular example. And pls, no Visual Studio or C# hatred.
Thanks in advance! :)
EDIT:
This is what I have managed to do so far, and it DOES NOT WORK!!!
MYSQL side, using HeidiSQL:
CREATE DEFINER=`root`#`localhost` PROCEDURE `login`(IN `stuff` VARCHAR(50), IN `pass` VARCHAR(50), OUT `param3` INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
set param3 = 0;
set param3 = (select count(*) from users where username=stuff and userpassword=pass);
select #param3;
END
And in C# side, I attempt to get this OUT parameter. Now, this is after multiple iterations, where I have gutted what the function used to be, and boiled it down to two issues: 1. The OUT parameters won't work, and 2. Even though Visual studio passes IN parameters, SQL refuses to recognize them.
protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
using (MySqlConnection con = new MySqlConnection(strcon))
{
con.Open();
MySqlCommand com = new MySqlCommand("CALL login(#stuff, #pass, #param3);", con);
com.CommandType = CommandType.Text;
com.Parameters.Add("#stuff", MySqlDbType.VarChar);
com.Parameters["#stuff"].Value = Login.UserName;
com.Parameters.Add("#pass", MySqlDbType.VarChar);
com.Parameters["#pass"].Value = Login.Password;
try
{
obj = com.ExecuteScalar();
objparam = com.Parameters["param3"].Value;
if (Convert.ToInt32(obj) != 0)
{
Response.Redirect("Welcome.aspx");
}
else
{
Login.PasswordRequiredErrorMessage = "invalid user name and password";
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
con.Close();
}
}
I believe the code and the pictures say more than I ever will.
C# DB Layer (DB Layer has conn as a connection string):
// Note: this is an instance (myDB in terms of the GUI Object)
using System.Data;
using MySql.Data.MySqlClient;
...
...
public long MultBySeven(long theNum)
{ // Call a Mysql Stored Proc named "multBy7"
// which takes an IN parameter, Out parameter (the names are important. Match them)
// Multiply the IN by 7 and return the product thru the OUT parameter
long lParam = 0;
using (MySqlConnection lconn = new MySqlConnection(connString))
{
lconn.Open();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = lconn;
cmd.CommandText = "multBy7"; // The name of the Stored Proc
cmd.CommandType = CommandType.StoredProcedure; // It is a Stored Proc
// Two parameters below. An IN and an OUT (myNum and theProduct, respectively)
cmd.Parameters.AddWithValue("#myNum", theNum); // lazy, not specifying ParameterDirection.Input;
cmd.Parameters.AddWithValue("#theProduct", MySqlDbType.Int32);
cmd.Parameters["#theProduct"].Direction = ParameterDirection.Output; // from System.Data
cmd.ExecuteNonQuery(); // let it rip
Object obj = cmd.Parameters["#theProduct"].Value;
lParam = (Int32)obj; // more useful datatype
}
}
return (lParam);
}
C# GUI Test Layer:
private void btnTestInOut_Click(object sender, EventArgs e)
{ // This GUI Layer call thru the use of a business object or data layer object (`myDB`)
long localHere = myDB.MultBySeven(11);
}
Stored Procedure (take a number, multiply by 7):
DROP PROCEDURE IF EXISTS multBy7;
DELIMITER $
CREATE PROCEDURE multBy7
( IN myNum INT,
OUT theProduct INT
)
BEGIN
SET theProduct=myNum*7;
END$
DELIMITER ;
Debug View (read: it works. 11x7=77):
MySQL Connector 6.9.9.0 / Visual Studio 2015:
See also 5.10.1 Using Stored Routines from Connector/Net, age unknown.
You should set up a reference to the parameter
var param3 = new MySqlParameter();
param3.Direction = ParameterDirection.Output;
param3.DbType = // whatever the dbtype for int is or whatever you need.
param3.ParameterName = "param3";
com.Parameters.Add(param3);
in your try block, insert
var result = com.ExecuteReader(); // or com.ExecuteScalar();
after you execute that, your parameter should have the value populated and you should be able to also read the SP results (select).
var paramResult = param3.Value;
Reading the results of the SP can be done as reader or scalar.
// execute reader
while (result.Read()) {
int value = result.GetInt32(0));
} /* read returned values in result */
// execute scalar
int value;
if (int.TryParse($"{result}", out value)) {
/* do something with value */
}
/************************************************/
This block should get you where you need to go
const string strcon = "whatevs";
using (MySqlConnection con = new MySqlConnection(strcon))
{
const string sql = "login";
MySqlCommand com = new MySqlCommand(sql, con);
com.CommandType = CommandType.StoredProcedure;
var stuffParam = new MySqlParameter("stuff", stuffValue);
var passParam = new MySqlParameter("pass", passValue);
var param3Param = new MySqlParameter();
param3Param.ParameterName = "param3";
param3Param.DbType = DbType.Int32;
param3Param.Direction = ParameterDirection.Output;
com.Parameters.Add(stuffParam);
com.Parameters.Add(passParam);
com.Parameters.Add(param3Param);
try
{
var scalarResult = com.ExecuteScalar();
// because you used select #param3 in your sp.
int value;
if (int.TryParse($"{scalarResult}", out value))
{
//do something with value
}
//// because you used select #param3 in your sp.
//var readerResult = com.ExecuteReader();
//if (readerResult.Read())
//{
// //
// value = readerResult.GetInt32(0);
//}
int param3Returned;
if(int.TryParse($"{param3Param.Value}", out param3Returned))
{
// do something with param3Returned
}
}
catch (Exception ex)
{
// do something with ex
}
}
I want to execute a stored procedure inside a Web Method. It is a select statement in the stored procedure. I tried with the following code. However, the result not successful. The result should return 1 but it is always returning -1. Does anyone have any idea? Please help.
Here is the web service .asmx code:
public class retrieveLoan : System.Web.Services.WebService
{
string constring = "Data Source=DIT-NB1260382;Initial Catalog=Experiment;Integrated Security=True";
SqlConnection myConn;
[WebMethod(Description="Simple Example")]
public int GetResult(int id, int age)
{
Int32 numberofRecords = 0;
System.Data.DataSet workDS = new System.Data.DataSet();
SqlCommand objCommand = default(SqlCommand);
//Create a command object
objCommand = new SqlCommand();
//prepare the command for retreiving
objCommand.CommandType = System.Data.CommandType.StoredProcedure;
objCommand.CommandText = "myprocedure2";
//open the connection
myConn = new SqlConnection(constring);
myConn.Open();
objCommand.Connection = myConn;
try
{
numberofRecords = (Int32)objCommand.ExecuteScalar();
return numberofRecords;
}
catch (Exception)
{
return -1;
}
finally
{
myConn.Close();
}
}
}
and my store procedure:
ALTER PROCEDURE [dbo].[myprocedure2]
(
#puserid int,
#page int
)
AS
BEGIN
select * from userdet where userid = #puserid and age = #page
END
I believe that executing this stored procedure without parameters would return an exception.
First of all, for you to see the Exception, in the catch declaration, you should try and declare the Exception explicitly, like this:
try
{
numberofRecords = (Int32)objCommand.ExecuteScalar();
return numberofRecords;
}
catch (Exception ex)
{
//here you can enter into debug mode and see the exception "ex"
return -1;
}
finally
{
myConn.Close();
}
When you see the exception, you can quickly solve the problem.
Next, you should add the parameters as NULL into your stored procedure (so they can accept null values), OR, if you do not, you must add these parameter in C# code, and send them some values.
Also, i would like to point the fact that if you want to retrieve a COUNT, you should modify your stored procedure as following:
ALTER PROCEDURE [dbo].[myprocedure2] ( #puserid int, #page int )
AS
BEGIN
select COUNT(userid) from userdet where userid = #puserid and age = #page
END
Hope this solves your issues here.
You're not providing a lot of info, so hard to answer, but here's a way forward:
Change catch (Exception) into catch (Exception ex), then see what that exception contains, either by returning it, or by analyzing it in debug mode.
If you publish your project in debug mode, you can connect to it and debug it using Tools > Attach to Process and connect to the process called w3wp.exe (if there are more than one of them, look for the one with the correct version of .Net under the Type-column).
Your query is "select * from userdet". What ExecuteScalar() does is pick the first cell value. Now you are type casting this to int. if your first cell value is a string type or some other type. you will definitely receive a error. And that will return -1. Please define the column name in your select query or count like this "select count(*) from userdet". Check ur query.
I am trying to call a function that returns a decimal value to my C# website. When I call the function inside SQL Server the trailing decimal values are present. But when it gets passed into C# the trailing decimals are missing.
This is my SQL Server stored procedure being called:
declare #MonthlyTotal as decimal(10,2)
set #MonthlyTotal=(select cast((Linetotal * Subtotal) as decimal(10,2)))
return #MonthlyTotal
Inside my C# server code I am receiving the stored procedure value. But it does not come with the trailing decimals.
SqlConnection sqlConnection = new SqlConnection(Connection);
SqlCommand cmd4 = new SqlCommand();
cmd4.Connection = sqlConnection;
cmd4.CommandType = CommandType.StoredProcedure;
cmd4.CommandText = "GetTBSMonthlyTotalService";
SqlParameter JobParam = new SqlParameter("MonthlyTotal", SqlDbType.Decimal, 10);
JobParam.Precision = 10;
JobParam.Scale = 2;
JobParam.Direction = ParameterDirection.ReturnValue;
cmd4.Parameters.Add(JobParam);
try
{
sqlConnection.Open();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
cmd4.ExecuteNonQuery();
double ID = Double.Parse((cmd4.Parameters[0].Value.ToString()));
sqlConnection.Close();
return ID;
The return value of a stored procedure can only be an integer type (INT, BIGINT - see the relevant MSDN docs on RETURN) and it's only used to signal success (or failure) of the stored procedure.
If you need to return anything else - including decimal - you need to use either an OUTPUT parameter, or a SELECT statement that selects that value as a result set for the stored procedure.
I have the following SQL stored procedure with one input parameter and one out parameter.
CREATE PROCEDURE [dbo].[spCanUserEdit]
(
#username nvarchar(255)
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #CanEdit bit
SELECT
#CanEdit = CanUserEdit
FROM tblUsers
WHERE username = LOWER(#username)
RETURN SELECT #CanEdit
END
GO
In the stored procedure above CanUserEdit column in tblUsers is bit type column and with default value to 0. Now when I execute this procedure in Management Studio it runs fine but when i use command.ExecuteScalar() in my C# code, it always returns null. Could anyone please tell me what I am doing wrong here.
Following is my C# method
public static bool CanUserEdit(string userName)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[Constants.ConnectionStringName].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "spCanUserEdit";
cmd.Connection = conn;
cmd.Parameters.Add(new SqlParameter("#username", userName));
conn.Open();
bool canEdit = (bool)cmd.ExecuteScalar();
return canEdit;
}
}
}
The problem is in the way you return data. If you want to use ExecuteScalar, you should not RETURN but instead simply SELECT.
Try to change the SP as following:
CREATE PROCEDURE [dbo].[spCanUserEdit]
(
#username nvarchar(255)
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #CanEdit bit
SELECT
#CanEdit = CanUserEdit
FROM tblUsers
WHERE username = LOWER(#username)
SELECT #CanEdit
RETURN 0
END
GO
If you can't change the SP, but the code, the solution is to read parameter '#ReturnValue' with ExecuteNonQuery.
Use a scaler function instead of a stored procedure. SQL functions are much easier to setup and they return a scaler value by default so no 'OUTPUT' or return variable declarations necessary. Example:
CREATE FUNCTION [dbo].[ScalerFnExample]()
RETURNS VARCHAR(50)
AS
BEGIN
RETURN (SELECT TOP 1 Thing FROM Examples.dbo.Stuff)
END
C# Example:
public string SqlScalerFnExample()
{
string retVal = default;
try
{
using (SqlConnection sqlConnection = new SqlConnection("Server=127.0.0.1;Database=Examples;Trusted_Connection=True;"))
{
SqlCommand userFn = new SqlCommand("SELECT dbo.ScalerFnExample()", sqlConnection);
sqlConnection.Open();
retVal = (string)userFn.ExecuteScalar();
}
}
catch (Exception ex)
{
Console.WriteLine($"SqlScalerFnExample() - Exception: {ex.Message}");
}
return retVal;
}