C# guid and SQL uniqueidentifier - c#

I want to create a GUID and store it in the DB.
In C# a guid can be created using Guid.NewGuid(). This creates a 128 bit integer. SQL Server has a uniqueidentifier column which holds a huge hexidecimal number.
Is there a good/preferred way to make C# and SQL Server guids play well together? (i.e. create a guid using Guid.New() and then store it in the database using nvarchar or some other field ... or create some hexidecimal number of the form that SQL Server is expecting by some other means)

Here's a code snippet showing how to insert a GUID using a parameterised query:
using(SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using(SqlTransaction trans = conn.BeginTransaction())
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.Transaction = trans;
cmd.CommandText = #"INSERT INTO [MYTABLE] ([GuidValue]) VALUE #guidValue;";
cmd.Parameters.AddWithValue("#guidValue", Guid.NewGuid());
cmd.ExecuteNonQuery();
trans.Commit();
}
}

SQL is expecting the GUID as a string. The following in C# returns a string Sql is expecting.
"'" + Guid.NewGuid().ToString() + "'"
Something like
INSERT INTO TABLE (GuidID) VALUE ('4b5e95a7-745a-462f-ae53-709a8583700a')
is what it should look like in SQL.

You can pass a C# Guid value directly to a SQL Stored Procedure by specifying SqlDbType.UniqueIdentifier.
Your method may look like this (provided that your only parameter is the Guid):
public static void StoreGuid(Guid guid)
{
using (var cnx = new SqlConnection("YourDataBaseConnectionString"))
using (var cmd = new SqlCommand {
Connection = cnx,
CommandType = CommandType.StoredProcedure,
CommandText = "StoreGuid",
Parameters = {
new SqlParameter {
ParameterName = "#guid",
SqlDbType = SqlDbType.UniqueIdentifier, // right here
Value = guid
}
}
})
{
cnx.Open();
cmd.ExecuteNonQuery();
}
}
See also: SQL Server's uniqueidentifier

Store it in the database in a field with a data type of uniqueidentifier.

// Create Instance of Connection and Command Object
SqlConnection myConnection = new SqlConnection(GentEFONRFFConnection);
myConnection.Open();
SqlCommand myCommand = new SqlCommand("your Procedure Name", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#orgid", SqlDbType.UniqueIdentifier).Value = orgid;
myCommand.Parameters.Add("#statid", SqlDbType.UniqueIdentifier).Value = statid;
myCommand.Parameters.Add("#read", SqlDbType.Bit).Value = read;
myCommand.Parameters.Add("#write", SqlDbType.Bit).Value = write;
// Mark the Command as a SPROC
myCommand.ExecuteNonQuery();
myCommand.Dispose();
myConnection.Close();

Related

Calling stored procedure with parameter to return list

I have a stored procedure with parameters, which i want to submit the parameters in a view which returns a index of the list. How do i go about this in my controller
CREATE PROCEDURE [dbo].[spFlugReport]
(
#AccNo INTEGER,
#DateFrom DATE,
#DateTo DATE
)
AS
BEGIN
SELECT *
FROM [dbo].[KIRData]
WHERE AccNo = #AccNo
AND StartDate >= #DateFrom
AND EndDate <= #DateTo
AND Prod = 'Air'
END
C# code:
public ActionResult Report()
{
using(DataModel db = new DataModel())
{
SqlParameter[] param = new SqlParameter[] {
new SqlParameter("#AccNo ,"),
new SqlParameter("#DateFrom ,"),
new SqlParameter("#DateTo ,")
};
}
}
welcome to stack overflow. Here is a useful link that could help you to achieve what you need to do.
https://csharp-station.com/Tutorial/AdoDotNet/Lesson07
and here is one with a similar question to your problem How to execute a stored procedure within C# program
However, here is an quick example of what you need to pass a parameter to a stored procedure.
// create and open a connection object
SqlConnection conn = new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();
// 1. create a command object identifying the stored procedure
SqlCommand cmd = new SqlCommand("CustOrderHist", conn);
// 2. set the command object so it knows to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which will be passed to the stored procedure
cmd.Parameters.Add(new SqlParameter("#CustomerID", custId));
// execute the command
SqlDataReader rdr = cmd.ExecuteReader();
Hope this helps you.
I believe you're looking for something like this. If not, could you provide more detail.
DataTable database = new DataTable();
string dbString = ConfigurationManager.ConnectionStrings["YourConnection"].ConnectionString;
using (SqlConnection con = new SqlConnection(dbString))
using (SqlCommand cmd = new SqlCommand("dbo.spFlugReport", con))
{
using(DataModel db = new DataModel())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#AccNo", AccNo);
cmd.Parameters.AddWithValue("#DateFrom", DateFrom);
cmd.Parameters.AddWithValue("#DateTo", DateTo);
con.Open();
cmd.ExecuteNonQuery();
}
}
This link is how you created a ConnectionString for YourConnection: https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/introduction/creating-a-connection-string

c# Inserting int value into SQL table

I want to insert some data into SQL table. But while inserting int no matter what I've tried I get error:
System.Data.SqlClient.SqlException: 'Conversion failed when converting
the varchar value '#ID' to data type int.'
I even manually set ID to 1 simply to be 100 % sure it's int but still get that error
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES ('#ID','#secondvar')";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
int ID = 1;
cmd.Parameters.AddWithValue("#ID", ID);
cmd.Parameters.AddWithValue("#secondvar", tableModel.secondvar);
connection.Open();
int result = cmd.ExecuteNonQuery();
Remove the quotes around the values. The framework handles that already.
VALUES ('#ID','#secondvar')
should be
VALUES (#ID,#secondvar)
ID is an integer so it must not be between '':
Change this line:
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES ('#ID','#secondvar')";
to this:
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES (#ID,#secondvar)";
And its better avoid using AddWithValue instead use it like:
String query = "INSERT INTO table(dbo.table.ID, dbo.table.secondvar)
VALUES (#ID,'#secondvar')";
using (SqlCommand cmd = new SqlCommand(query, connection))
{
int ID = 1;
cmd.Parameters.Add("#ID", SqlDbType.Int).Value = ID;
cmd.Parameters.Add("#secondvar", SqlDbType.VarChar).Value = somevalue;
//rest of the code
}

How to retrieve ##Identity following an ExecuteNonQuery?

I'm using the ExecuteNonQuery function and stored procedure to insert a new record in an MSSQL database.
During testing the insert of the new record is successful. But my second call to ExecuteScalar and get the newly inserted record's ID fails. The reason for the failure according to the debugger is:
ExecuteScalar requires an open and available Connection. The
connection's current state is closed.
Looking at this error it explains that the connection has been closed after the initial call to ExecuteNonQuery. Meaning that my code to get the ID won't have a valid connection to query with.
Question:
How can you retrieve ##Identity following an ExecuteNonQuery?
This is the piece of code that performs the insert in the DAL:
Database db = GetConnectionString();
string sqlCommand = "CREATE_RECORD";
string idQuery= "Select ##Identity";
int recID = 0;
using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand))
{
db.AddInParameter(dbCommand, "#Application", DbType.String, escalation.Application);
db.AddInParameter(dbCommand, "#UpdatedTime", DbType.DateTime, escalation.UpdatedTime);
db.ExecuteNonQuery(dbCommand);
dbCommand.CommandText = idQuery;
recID = (int)dbCommand.ExecuteScalar();
return recID ;
}
DISCLAIMER: This is a bad idea - the correct solution is server-side (server in this case is SQL Server).
You may be able to do this if you use SCOPE_IDENTITY() (which you should anyway - ##IDENTITY is not guaranteed to be your insert's identity) and execute your command as CommandType.Text instead of CommandType.StoredProcedure
WARNING: Serious security implications here, most notably SQL Injection Attack possibility:
Database db = GetConnectionString();
string sqlCommand = $"CREATE_RECORD '{escalation.Application}', '{escalation.UpdatedTime}'";
string idQuery= "Select SCOPE_IDENTITY()"
int recID = 0;
using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand))
{
dbCommand.CommandType = commandType.Text;
db.ExecuteNonQuery(dbCommand);
dbCommand.CommandText = idQuery;
recID = (int)dbCommand.ExecuteScalar();
return recID;
}
Of course, if you go this route, you might as well combine both commands into a single query:
Database db = GetConnectionString();
string sqlCommand = $"CREATE_RECORD '{escalation.Application}', '{escalation.UpdatedTime}'; Select SCOPE_IDENTITY()";
int recID = 0;
using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand))
{
dbCommand.CommandType = commandType.Text;
//TODO: Open connection using your db object
recID = (int)dbCommand.ExecuteScalar();
//TODO: Close connection using your db object
return recID;
}
Again, I stress that the correct solution is to fix this in SQL, not in C#. Use at your own risk!
You should create and open connection for each query and dispose it after query. Don't worry, there are connection pool in ADO and connection will not be physically established and closed each time. It's only a hint for ADO.NET.
int recID = 0;
string connStr = ProcThatGivesYouConnectionString();
using (SqlConnection con = new SqlConnection(connStr))
{
con.Open();
SqlCommand command = new SqlCommand("CREATE_RECORD", con);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#Application", escalation.Application);
command.Parameters.AddWithValue("#UpdatedTime", escalation.UpdatedTime);
command.ExecuteNonQuery();
}
using (SqlConnection con2 = new SqlConnection(connStr))
{
con2.Open();
SqlCommand command = new SqlCommand("Select ##Identity", con2);
recID = (int)command.ExecuteScalar();
}
Also you can execute both queries in one command if you want:
int recID = 0;
string connStr = ProcThatGivesYouConnectionString();
using (SqlConnection con = new SqlConnection(connStr))
{
con.Open();
SqlCommand command = new SqlCommand("
EXEC CREATE_RECORD #Application = #Application, #UpdatedTime = #UpdatedTime
SELECT ##Identity", con);
command.Parameters.AddWithValue("#Application", escalation.Application);
command.Parameters.AddWithValue("#UpdatedTime", escalation.UpdatedTime);
recID = (int)command.ExecuteScalar();
}
object r = command.ExecuteScalar();
Convert.ToInt32(r.ToString());
To prevent the ExecuteScalar gets Specified cast is not valid error , use above

Web API to call the stored Procedure and return Result

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

How do I store a SQL stored procedure result that returns a row or a column value into an ASP.NET C# variable?

I have a SQL stored procedure that returns a column value (SQL data type: nchar(1)). The stored procedure runs and comes back with desired value when a parameter is passed. Based on this returned value, I want to divert the program flow. For this I need to read the value returned in an ASP.NET C# variable, but I am not sure how can I do this.
create procedure sproc_Type
#name as nchar(10)
AS
SELECT Type FROM Table WHERE Name = #name
I want to read Type value in .cs file and want to save it for later use.
SqlConnection conn = null;
SqlDataReader rdr = null;
conn = new
SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();
// 1. create a command object identifying
// the stored procedure
SqlCommand cmd = new SqlCommand(
"Stored_PROCEDURE_NAME", conn);
// 2. set the command object so it knows
// to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which
// will be passed to the stored procedure
cmd.Parameters.Add(
new SqlParameter("#PARAMETER_NAME", PARAMETER_VALUE));
// execute the command
rdr = cmd.ExecuteReader();
// iterate through results, printing each to console
while (rdr.Read())
{
var result = rdr["COLUMN_NAME"].ToString();
}
string connectionString = "(your connection string here)";
string commandText = "usp_YourStoredProc";
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(commandText, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 600;
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
// your code to fetch here.
}
conn.Close();
}

Categories

Resources