I have the below Controller that gets the account as the input parameter, which connects to the Sql server and will have to call the stored procedure passing account.The stored procedure inserts a new record if the Account is not present and updates it when already in there
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";
Below is the ConnectionString in web.config
<connectionStrings>
<add name="DBConnection"
providerName="System.Data.SqlClient"
connectionString="Data Source=ServerName;Initial Catalog=DatabaseName;Integrated Security=True;MultipleActiveResultSets=True" />
</connectionStrings>
The stored procedure is like
ALTER 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.CounterSeq = prj.CounterSeq+1
WHEN NOT MATCHED THEN INSERT (AccountID,CounterSeq)
VALUES (tt.AccountID, 1);
COMMIT TRANSACTION;
END;
where the table type is created with
CREATE TYPE account_TT AS TABLE
(
AccountID nvarchar(50),
)
GO
When I try to call the API it doesnot throw any exception but neither creates/update any records with the stored procedure. I tried to debug the adding breakpoints. I see the in
DbConnection.Open();
Looks like the connection is not opened. I am able to connect to the SQL server from the same server I am working on though SQL Management Studio. Can anyone please suggest me what could be the issue.
You probably have open connection.Correct way of opening connection
string strcon = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
using(SqlConnection dbConnection = new SqlConnection(strcon))
{
if (dbConnection.State==ConnectionState.Closed)
{
con.Open();
}
}
you didn't connect to data base correct. try this:
using (var connection = new SqlConnection(ConnectionString))
using (var command = new SqlCommand(commandText, connection) { CommandTimeout = 160, CommandType = commandType })
using (var dataAdaptor = new SqlDataAdapter(command))
{
command.Parameters.AddRange(parameters);
connection.Open();
dataAdaptor.Fill(dS);
}
Related
The stored procedure in SQL works perfectly with the desired result.
ALTER PROCEDURE [dbo].[My_StoredProc]
(#autoidx int,
#r varchar(max) OUTPUT)
--with encryption
AS
BEGIN
-- ... some code here ...
END
Trying to call the stored procedure in VS 2019 using ODBC command but I get getting an error :
Procedure or function My_StoredProc expects parameter #autoidx, which was not supplied.
My code:
string connectionString = String.Format("DSN={0};uid=my_user;pwd=my_pwd", toolStripComboBoxDSN.Text);
// OdbcCommand DbCommand = new OdbcCommand("My_StoredProc", DbConnection);
// DbCommand.CommandType = CommandType.StoredProcedure;
//DbCommand.Parameters.AddWithValue("#autoidx", this.AutoIndex); //this.AutoIndex has value
//DbCommand.Parameters.Add("#r", OdbcType.VarChar,500);
//DbCommand.Parameters["#r"].Direction = ParameterDirection.Output;
//DbConnection.Open();
//DbCommand.ExecuteNonQuery();
//string s = (string)DbCommand.Parameters["#r"].Value;
//Code below is working. With a major change in CommandType
OdbcCommand DbCommand = new OdbcCommand(" EXEC dbo.My_StoredProc #autoidx=? ", DbConnection);
DbCommand.CommandType = CommandType.Text;
DbCommand.Parameters.Add("?", OdbcType.Int).Value = this.AutoIndex;
DbConnection.Open();
var s = DbCommand.ExecuteScalar();
I had one opinion:
1.- Try to change this
DbCommand.Parameters.AddWithValue("#autoidx", this.AutoIndex);
for this:
DbCommand.Parameters.Add("#autoidx", SqlDbType.Int);
DbCommand.Parameters["#autoidx"].Value = this.AutoIndex;
2.- Check you DbConnection, sometimes this contain other database for example db_developer instead of db_production.
Try to use the System.Data.SqlClient native SQL client to SQL Server, and use proper using blocks and proper parameter definition - something like this:
// standard SQL Client connection string
string connectionString = "......";
// define connection and command in proper "usinh" blocks
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("dbo.My_StoredProc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// define parameters properly
cmd.Parameters.Add("#autoidx", SqlDbType.Int);
cmd.Parameters.Add("#r", SqlDbType.VarChar, -1).Direction = ParameterDirection.Output;
// set values to parametesr
cmd.Parameters["#autoidx"] = this.AutoIndex;
// open connection, execute procedure, close connection
conn.Open();
int rowsAffected = cmd.ExecuteNonQuery();
string s = cmd.Parameters["#r"].Value?.ToString();
conn.Close();
}
I'm trying to write a log into another database inside a transaction so that the log will survive even if the transaction is rolled back. I've read this answer which says:
One possibility is to use a CLR stored procedure to do the logging. This can open its own connection to the database outside the transaction and enter and commit the log data.
So I created CLR stored procedure using this article:
[SqlProcedure]
public static void Voice(SqlString procedureName, SqlInt32 id)
{
Connection = new SqlConnectionStringBuilder();
Connection.ContextConnection = true;
using (TransactionScope transScope = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(Connection.ToString()))
{
conn.Open();
SqlCommand cmdInsert = conn.CreateCommand();
cmdInsert.CommandText = sql;
cmdInsert.Parameters.Add("#id", SqlDbType.Int);
cmdInsert.Parameters[0].Value = id;
cmdInsert.Parameters.Add("#procedureName", SqlDbType.NVarChar);
cmdInsert.Parameters[1].Value = procedureName;
cmdInsert.ExecuteNonQuery();
}
transScope.Complete();
}
}
However, data is not saved afer I executed and rolled back stored procedure in SQL Server:
BEGIN TRAN
EXEC dbo.SayHelloVoice #id = 1,
#procedureName = N'FooProcedure'
ROLLBACK TRAN
We have three environments:
dev. Server name is Q-SQL001
test. Server name is Q-SQL002
prod. Server name is Q-SQL003
So this CLR stored procedure should work on all environments.
Could you say what I am doing wrong?
Any help would be greatly appreciated!
UPDATE:
So the work version looks like this. Big thanks to the #Milney:
var serverName = string.Empty;
var dbName = string.Empty;
serverName = SqlExecuteScalar("SELECT ##SERVERNAME");
dbName = SqlExecuteScalar("SELECT DB_NAME()");
SqlConnectionStringBuilder sqlConn = new SqlConnectionStringBuilder();
sqlConn.InitialCatalog = dbName;
sqlConn.DataSource = serverName;
sqlConn.IntegratedSecurity = true;
sqlConn.ContextConnection = false;
sqlConn.Enlist = false;
sqlConn.ApplicationName = "New application";
var sql = "USE FooDatabase
INSERT INTO dbo.MyTable ..."
using (SqlConnection conn2 = new SqlConnection(sqlConn.ConnectionString))
{
conn2.Open();
SqlCommand cmdInsert = conn2.CreateCommand();
cmdInsert.CommandText = sql;
cmdInsert.Parameters.Add("#id", SqlDbType.Int);
cmdInsert.Parameters[0].Value = storeTime;
cmdInsert.Parameters.Add("#messageText", SqlDbType.NVarChar);
cmdInsert.Parameters[1].Value = messageText;
cmdInsert.ExecuteNonQuery();
}
If you use:
Connection.ContextConnection = true;
Then it's going to use the same connection that the CLR Sproc is running in - you need to open a new connection.
click here to see the tableI wrote a stored procedure to get the table value. But I don't know how to write the C# code to call the stored procedure. I want to run it in a console.
My stored procedure:
alter procedure sampleone (#createdOn nvarchar(200))
as
begin
select *
from sa_test
where createdOn = #createdOn
end
Sample trial code:
try
{
string connectionString = "(CString)";
string commandText = "sampleone";
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(commandText, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#createdOn",25/10/2017);
cmd.CommandTimeout = 600;
conn.Open();
int affectedRows = cmd.ExecuteNonQuery();
conn.Close();
}
}
catch
{
}
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="CString" connectionString="data source=34.193.27.161;User Id=sa; Pwd=RCK$1234; Initial Catalog=rs" providerName="System.Data.SqlClient"/>
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Can anyone help me to get the C# code?
Soo, based on what you really want then your script can look different. However, you should really consider where you want to put your logic. Do you want your stored procedure to insert data or do you want C# to do it? Otherwise here is an example where your stored procedure is used for inserting data:
NOTE
My date is propberly different due to i live in another country - Just change the date back to your desired result and dateformat.
NOTE2
Consider making your createdON variable in your stored procedure as a date instead of nvarchar also.
SQL Code
--Build table for test inserts
CREATE TABLE dbo.testtable (
Name nvarchar(50),
Createdon date
)
--Insert dummy values to sa_test
INSERT INTO sa_test
values('Thomas','2017-10-10'),
('Hans','2017-12-25')
--Edit stored procedure to not just select but also insert data based on #createdOn variable
create procedure sampleone (#createdOn nvarchar(200))
as
begin
insert into testtable (Name,createdon)
select *
from sa_test
where createdon= #createdOn
end
C# Code
string conn = "Server=EGC25199;Initial Catalog=LegOgSpass;Integrated Security=True";
string query = "sampleone";
SqlConnection connDatabase = new SqlConnection(conn);
connDatabase.Open();
SqlCommand cmd = new SqlCommand(query, connDatabase);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#createdOn", SqlDbType.Date).Value = "2017-10-10";
cmd.ExecuteNonQuery();
connDatabase.Close();
C# Code with datatable and print to console
string conn = "Server=EGC25199;Initial Catalog=LegOgSpass;Integrated Security=True";
string query = "sampleone";
DataTable dt = new DataTable();
SqlConnection connDatabase = new SqlConnection(conn);
connDatabase.Open();
SqlCommand cmd = new SqlCommand(query, connDatabase);
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#createdOn", SqlDbType.Date).Value = "2017-10-10"; //Adding the selected items to parameter #check
cmd.ExecuteNonQuery();
da.Fill(dt);
foreach( DataRow row in dt.Rows)
{
Console.WriteLine();
for (int x = 0; x < dt.Columns.Count; x++)
{
Console.Write(row[x].ToString() + " ");
}
}
}
connDatabase.Close();
Result with console print
Result
My testtable is empty at first
sa_test table has 2 values i can select
When i then run my script my testtable looks like this:
cmd.Parameters.AddWithValue("#createdOn",25/10/2017);
should be like this and try :
cmd.Parameters.AddWithValue("#createdOn","25/10/2017");
You need to use ExecuteReader get return data from SP. Also there is TYPO while passing parameter.
cmd.Parameters.AddWithValue("#createdOn","25/10/2017");
Updated Code
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(commandText, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#createdOn","25/10/2017");
cmd.CommandTimeout = 600;
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
}
conn.Close();
}
You can follow this simple technique :
try
{
string connectionString = ConfigurationManager.ConnectionStrings["CString"].ConnectionString);
string commandText = "sampleone";
DataTable table = new DataTable();
using(var con = new SqlConnection(connectionString))
using(var cmd = new SqlCommand(commandText, con))
using(var da = new SqlDataAdapter(cmd))
{
cmd.Parameters.Add("#createdOn", SqlDbType.NVarChar, 50).Value = "25/10/2017";
cmd.CommandType = CommandType.StoredProcedure;
da.Fill(table);
}
}
catch
{
}
Using the above code, your stored procedure data will be populated to the datatable table. You can then use this table for various use, like processing the data, populating the data into a datagrid etc. Another benefit of this technique is, you even don't need to open/close the connection. That will be done implicitly by the DataAdapter da
I'm trying to update a table in my SQL Server database with text from an input box on my site;
My table is MemberSite.dbo.Users and the columns within this table are:
ID (Auto incrementing) UserName, Password, ApiKey, VeriF
It's not updating my SQL Server table.
What I want this to do: take the input text and put it in my SQL Server table against the user that is logged in.
Here is some code web.config :
<add name="WRITER"
connectionString="Data Source=localhost;Initial Catalog=MembershipSite;User ID=test;Password=test!"
providerName="System.Data.SqlClient" />
Backend to button click;
protected void Save_Click(object sender, EventArgs e)
{
SqlConnection conn = null;
try
{
string sql = "UPDATE dbo.Users SET ApiKey = #API, VeriF = #verif WHERE UserName = #username";
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["WRITER"].ConnectionString);
SqlCommand cmd = new SqlCommand(sql, conn);
SqlParameter api = new SqlParameter();
api.ParameterName = "#API";
api.Value = APIinput;
cmd.Parameters.Add(api);
SqlParameter verif = new SqlParameter();
verif.ParameterName = "#verif";
verif.Value = Veri;
cmd.Parameters.Add(verif);
SqlParameter UserN = new SqlParameter();
UserN.ParameterName = "#username";
UserN.Value = User.Identity.Name;
cmd.Parameters.Add(UserN);
conn.Open();
}
finally
{
if (conn !=null)
conn.Close();
}
}
Because you never execute your command. Just add:
cmd.ExecuteNonQuery();
after you open your connection.
Also use using statement to dispose your connection and command automatically instead of calling Close or Dispose methods manually. Like;
using(var conn = new SqlConnection(conString))
using(var cmd = conn.CreateCommand())
{
// Set your CommandText
// Add your parameters
// Open your connection
// Execute your command.
}
You have missed cmd.ExecuteNonQuery() after connection.Open(). That's why the values are not updated
How to use C# to add a column for a table of sql server?
For example, I want to execute the following sql in C# code:
alter table [Product] add
[ProductId] int default 0 NOT NULL
You should use a Command:
using (DbConnection connection = new SqlConnection("Your connection string")) {
connection.Open();
using (DbCommand command = new SqlCommand("alter table [Product] add [ProductId] int default 0 NOT NULL")) {
command.Connection = connection;
command.ExecuteNonQuery();
}
}
SqlCommand cmd2 = new SqlCommand();
// create columns for healed
cmd2 = new SqlCommand("ALTER TABLE TotalHeals ADD "+Healee+" INT", openCon);
cmd2.ExecuteNonQuery();
Funny how SqlCommand is different then DBCommand