I want to update a table through sql code executed in a c# application. To do this, I've used the alter data generated my MSSMS and manually saved it as an sql-file. The c# then reads the file and tries to execute it but it can't. If I use the sql code by itself it works, but not when read by the c# funtion. What's wrong with my c# code?
The sql code generated my MSSMS:
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.tTest ADD
NewColumn int NULL
GO
ALTER TABLE dbo.tTest SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
The c# code that reads it:
string content = string.Empty;
try
{
content = File.ReadAllText(string.Format(#"C:\temp\{0}.sql", name));
SqlConnection conn = new SqlConnection(ConnectionString);
SqlCommand command = new SqlCommand(content, conn);
command.Connection.Open();
command.ExecuteNonQuery();
command.Connection.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
The output that comes from the c# function (the console message):
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Each batch (ended with GO) should be sent separately in one command.ExecuteNonQuery(). This method is not to be used for multiple batches.
Split your query into several pieces (where GO is) and execute it step by step.
The core issue with the script you are trying to run is wrapping a transaction around query batches (A query batch is terminated with a GO statement in SQL Server Management Studio).
To do the operations in C# you can execute both statements in one query batch. They do not require to be separate. If you wrap them in one query in a SqlCommand object you do not need to handle transactions as there is an "implicit" transaction created.
A last point to look out for is proper disposal of the objects implementing IDisposable. The easiest way to do this in C# is by wrapping them in a using clause. Once you did that, there is no more need to call the Close method on the command/connection objects.
Combining all these remarks gives you the following code:
try
{
using(var conn = new SqlConnection(ConnectionString))
using(var command = new SqlCommand(
#"ALTER TABLE dbo.tTest ADD NewColumn int NULL;
ALTER TABLE dbo.tTest SET (LOCK_ESCALATION = TABLE);", conn))
{
conn.Open();
command.ExecuteNonQuery();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Related
I have a stored procedure in a myscript.sql file that looks like this:
CREATE PROCEDURE [dbo].[_GetUserID]
#EmailAddress NVARCHAR(254)
AS
DECLARE #UserID UNIQUEIDENTIFIER;
SELECT #UserID = [ID]
FROM [dbo].[User]
WHERE [EmailAddress] = #EmailAddress
PRINT #UserID
GO
I have some C# code that relies on Dapper to run this script. I can successfully run this script when I copy-and-paste it into Azure Data Studio. However, when I am trying to run this script from code, I get an error:
Incorrect syntax near 'GO'
My C# code looks like this:
try
{
var script = File.ReadAllText("<path to myScript.sql is here>");
using (var connection = new SqlConnection(dbConnectionString))
{
var command = connection.CreateCommand();
command.CommandText = script;
command.CommandType = CommandType.Text;
connection.Open();
command.ExecuteNonQuery();
}
Console.WriteLine("Success.");
}
catch (Exception ex)
{
Console.WriteLine($"Failed. Reason: '{ex.Message}')");
}
I don't understand why I can run myScript.sql from Azure Data Studio, however, it's not working from my C# code. I'm also creating tables using the same approach and it works fine. I'm not sure what I'm missing.
GO is not a valid T-SQL keyword - it's a separator that is used by SQL Server Management Studio and obviously also Azure Data Studio.
To fix this, just simply remove that GO line from your .sql script file and run it without this - should be just fine.
On a different note: having nothing but a PRINT statement in your stored procedure doesn't make a lot of sense - don't you want to actually SELECT #UserId to get that data sent back to the caller??
I am currently writing an application which involves a user being able to write the time to a database by clicking a button. The problem is that the data will be send to the database table, but it does not show the time in SQL Server Management Studio.
This is my query:
{
string query = "insert into Sign_In_Out_Table(Sign_In)Values('"+ timetickerlbl.ToString()+ "')";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#SignIn", DateTime.Parse (timetickerlbl.Text));
//cmd.ExecuteNonQuery();
MessageBox.Show("Signed in sucessfully" +timetickerlbl);
con.Close();
}
The datatype in SQL Server is set to datetime.
I'm open for suggestions to find a better way to capture the PC's time and logging it in a database.
Don't wrap the variable in ' when you are setting value with Parameters.Add(), or Parameters.AddWithValue() as they would wrap if needed.
The variable in here would be the value of Sign_In and not the Sign_In itself.
Always use Parameters.Add() instead of Parameters.AddWithValue():
string query = "insert into Sign_In_Out_Table(Sign_In) Values(#value)";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#value", SqlDbType.DateTime).Value = DateTime.Parse(timetickerlbl.Text);
Edit (Considering your comment):
If still it does not insert it, of course there is an error in your code, it could be a syntax error, invalid table or column name, connection problem ,... so put your code in a try-catch block (if it isn't already) and see what error you you get, it should give you a hint:
try
{
//the lines of code for insert
}
catch(Exception ex)
{
string msg = ex.Message;
// the above line you put a break point and see if it reaches to the break point, and what the error message is.
}
Your table does not contain your timestamp because you have commented the execution of your query. Presumably you added the comment because this line was throwing an error, remove the comment and share the error with us.
cmd.ExecuteNonQuery();
I have a very strange case of SQL connection timeout from an application written in C# .NET.
The SqlCommand.ExecuteNonQuery() is being used to sequentially execute several scripts in SQL Server, one after another. Each script contains a command to create just one table (no data update/insert/delete operations at all). For some reason, at one of the scripts, the SqlCommand.ExecuteNonQuery throws a timeout exception.
When I execute creation of all these tables in SQL Server Management Studio, they get executed just fine and almost instantaneously.
Does anyone has an idea what could be causing timeout when the tables are created from the application?
All sql scripts look similar like following:
SQL:
create table dbo.Test
(
Code varchar(10) not null
, Name varchar(50) not null
, other columns...
primary key
, unique key
, foreign key
)
The scripts are shipped from C# using this code:
try
{
using (SqlConnection conSQL = new SqlConnection ("[connection string]"))
{
using (SqlCommand cmdSQL = new SqlCommand(sSQL, conSQL))
{
cmdSQL.CommandTimeout = iTimeOut;
conSQL.Open();
cmdSQL.ExecuteNonQuery(); // this is where it jumps to catch part and
// throws out timeout exception
conSQL.Close();
}
}
}
catch(Exception ex)
{
throw (ex);
}
This is happening on the Test server, meaning nothing else is happening on the server while the application is executing these scripts.
You can override the default time out setting for sql transactions by updating the machine.config, which can be found here:
%windir%\Microsoft.NET\Framework\[version]\config\machine.config
64-bit
%windir%\Microsoft.NET\Framework64\[version]\config\machine.config
At the end of the machine.config add or update the following line:
<system.transactions>
<machineSettings maxTimeout="01:00:00" /> --> set this to desired value.
</system.transactions>
</configuration>
If the above doesn't work, you can specify the Timeout setting for SqlCommand through code as well:
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
// Setting command timeout in seconds:
command.CommandTimeout = 3600;
try {
command.ExecuteNonQuery();
}
catch (SqlException e) {
Console.WriteLine(e);
}
}
more information here
Just stop it from running and run again your problem will be solved.... It is generally occur first time only when their are lot of files to load maybe it is bug in visual studio.
New:
After stop try to refresh open Web page (in browser where error displays ) instead of relaunch it again...
I wrote this code, but it doesn't work. Gives Invalid object name 'Inventory'`. Any Suggestion?
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString =
#"Data Source=(local);Integrated Security=SSPI;" +
"Initial Catalog=AutoLot";
cn.Open();
string strSQL = "Select * From Inventory";
SqlCommand myCommand = new SqlCommand(strSQL, cn);
// Obtain a data reader a la ExecuteReader().
using (SqlDataReader mydatareader = mycommand.ExecuteReader())
{}
Check in Database Inventory table is present or not and if Present then both name should be same
If you've checked all your database settings, access rights and table definitions and still cannot get rid of that error?
It's because ASP.net cannot understand your SQL query - as shocking as that may sound.
I had the same problem, with UPDATE statements wanting to use aliases and not the usually expected dbo.myTable name definitions.
The simplest way to avoid this situation, where asp.net just doesn't parse SQL like SQL Server would (!!), is to place the code into a Stored Procedure.
This was my SQL directly from SQL Server 2005 and it worked perfectly as is...
UPDATE tsa
SET tsa.ActionComplete = #ActionComplete,
tsa.CompleteDate = GETDATE(),
tsa.Notes = #ActionNotes
FROM blahblah
WHERE blahblah
But for what ever reason, the ASP.net parser inside the SqlDataSource control could not make sense of it (even though it ran perfectly inside the GUI's Test Query feature!).
I was getting
invalid object name in 'tsa'
So I placed the lot inside a Stored Procedure...
USE [mydatabase];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
ALTER PROCEDURE [dbo].[spTETupdateActions]
#StudentID VARCHAR(10),
#ActionComplete INT = 0,
#ActionNotes VARCHAR(MAX),
#TETmeetingID INT,
#WeekNo INT,
#TETID INT,
#TETdate DATETIME,
#ActionItem VARCHAR(MAX)
WITH
EXEC AS CALLER AS
UPDATE tsa
SET tsa.ActionComplete = #ActionComplete,
tsa.CompleteDate = GETDATE(),
tsa.Notes = #ActionNotes
FROM blahblah
WHERE blahblah
GO
And voila! No more errors! Why? Because the parsing of the SQL is done inside SQL Server not ASP.net!
So, we've got this set of code that, for some reason, keeps timing out. It's not the stored procedure that it's running, because that runs fine. Also, if we remove the parameter from the c# code, the code runs. The parameter keeps breaking (causing it to time out) and we can't figure out why.
c#:
public static PTWViewList GetList(int studynumber)
{
PTWViewList tempList = new PTWViewList();
using (SqlConnection myConnection = new SqlConnection(AppConfiguration.cnARDB))
{
string spName = "ardb.PTWViewSelect";
SqlCommand myCommand = new SqlCommand(spName, myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("#study", studynumber);
myConnection.Open();
using (NullableDataReader myReader = new NullableDataReader(myCommand.ExecuteReader())) /*this is where the code times out*/
{
tempList = new PTWViewList();
while (myReader.Read())
{
tempList.Add(FillDataRecord(myReader));
}
myReader.Close();
}
}
tempList.ListCount = tempList.Count;
return tempList;
}
stored procedure:
CREATE PROCEDURE [ardb].[PTWViewSelect]
#studynumber int = NULL,
#quoteid uniqueidentifier = NULL,
#lineitemid uniqueidentifier = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT
[Study]
,[LineItemID]
,[QuoteID]
,[Total]
,[COOP]
,[VendorCost]
,[CustCost]
,[LineItemNumber]
,[StudyTypeCode]
,[GroupLeader]
,[PTWDate]
,[PONumber]
,[POStatus]
,[StudyDirector]
,[SL_DESC_L]
,[SL_Code]
,ProjectDescription
,CreatedBy
,chARProcess
,CODate
FROM
[ARDB].[dbo].[PTWView]
WHERE
(#studynumber is null or StudyNumber=#studynumber)
AND (#quoteid is null or QuoteID=#quoteid)
AND (#lineitemid is null or LineItemID = #lineitemid)
END
have you tried
myCommand.Parameters.AddWithValue("#studynumber", studynumber);
instead of:
myCommand.Parameters.AddWithValue("#study", studynumber);
EDIT
If passing parameters is the problem, then it comes down to how much time the stored procedure takes to execute. Default timeout for SQL server is usually 120 secs. You can add "Connect Timeout" to increase timeout in your DB connection string and check out.
** Old Answer -- Ignore **
Without stack trace, and taking your word that the stored procedure is fine, I am guessing that it is timing out due to the connection failure. The code is unable to connect to your DB server and hence timing out.
setting arithabort off made the sp take 45 seconds as opposed to 1. setting it back on changed it back to 1. I updated the stored procedure to set it on, no change in the app. Changed it to off, no change. I then removed the update and then the app worked fine.
I believe what happened is that updating the stored procedure caused it to recompile, fixing the issue. I'm not 100% sure on this though.
One thing could be the ARITHABORT setting, set it to ON...NET defaults to OFF
run the proc in SSMS with ARITHABORT set to OFF and see if it runs slower now like from .NET
example
MyConnection.Execute "SET ARITHABORT ON"
Another thing is that your WHERE clause is not optimal, take a look at Do you use Column=#Param OR #Param IS NULL in your WHERE clause? Don't, it doesn't perform
does the proc run slow with parameters in SSMS? Can you show the execution plan?