Run TSQLScripts via the Web Page in c# ASP.Net - c#

I am trying to build the Web Page which can be used to run the TSQL scripts online.
My DB has so many databases and I am using the System Administrator account to execute these scripts.
After building the web page,
I can run the simple CRUD statements successfully in all databases
I can run the DML statements only for the default connected database, which is MyDB1.
Whenever, I create the new Object, it sits in the MyDB1. But I want to run / create objects in another DB.
I tried to run the following command, which is very simple and it works perfectly in SSMS.
USE MyDB2
GO
CREATE PROCEDURE [dbo].MyProc
AS
BEGIN
INSERT INTO
dbo.Table1
(
FieldA
, FieldB
, FieldC
)
VALUES
(
'AAA'
, 'BBB'
, 'CCC'
)
END
But I am getting the error message:
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
My c# code to execute the posted script is here:
DataTable dt = new DataTable();
try
{
using (SqlConnection cn = new SqlConnection("MyConnString"))
{
cn.Open();
SqlCommand cmd = new SqlCommand(sql, cn);
using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (dr.HasRows)
{
dt.Load(dr);
}
dr.Close();
}
cn.Close();
}
}
catch (Exception ex)
{
//Log Error
}
If I removed, USE statement, it was ok, but it created the object in the default DB which is MyDB1. How I can tweak my code to run it in MyDB2?

USE is an SSMS command, not a SQL statement.
Change your connect string to specify the appropriate database.

Related

SQL request working fine in SQL Server Management Studio but returning an error when send with sqlCommand C#

I have this statement:
SELECT [nozzles].[nozzle_tag],[nozzles].[id]
FROM [dispensers]
INNER JOIN [nozzles]
ON [dispenser_id] = [dispensers].[id]
INNER JOIN (SELECT * FROM assets
WHERE [i4_Device_Name] = 'EH004T_SOURCE2'
AND [i4_site_name] = 'Les Loges - H2e Station (EH004R)')assets
ON [asset_id] = [assets].[id]
WHERE [dispenser_tag] ='Dispenser 2';
It works perfectly fine when I execute it inside SSMS.
The problem is, when run this SQL by using SQLcommand, I get an error with this message:
Incorrect syntax near 'Loges'.
I don't understand why.
The command above is extracted from a log file, it is exactly what is send using SQLCommand.
C# code is:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(HySoSQLCommandBuilder.GetAllNozzleOfDispenser(locationID, dispenserTag), connection))
{
logger.Info("SQL request {request}", HySoSQLCommandBuilder.GetAllNozzleOfDispenser(locationID, dispenserTag));
using (SqlDataReader reader = command.ExecuteReader())
{
try
{
while (reader.Read())
if (reader.HasRows)
{
list.Add(new nozzle((string)reader["nozzle_tag"], (int)reader["id"]));
}
}
catch { }
}
}
With HySoSQLCommandBuilder.GetAllNozzleOfDispenser() being fairly straight forward:
public static string GetAllNozzleOfDispenser(AssetLocationID assetLocation, string dispenserTag)
{
return $#"SELECT [nozzles].[nozzle_tag],[nozzles].[id]
FROM [dispensers]
INNER JOIN [nozzles]
ON [dispenser_id] = [dispensers].[id]
INNER JOIN (SELECT * FROM assets
WHERE [i4_Device_Name] = '{assetLocation.i4DeviceName}'
AND [i4_site_name] = '{assetLocation.i4SiteName}')assets
ON [asset_id] = [assets].[id]
WHERE [dispenser_tag] ='{dispenserTag}';";
}
None of the injected values are accessible from outside the code. They do not come form a editable field accessible from a user. If SQL injection happens, then that means that it is in the source, done by someone that worked on the code, and can already do whatever they want to the database without the need to encode an SQL injection.
changed the code so it uses SQLparameters instead and now it's working. I don't understand why it wasn't working and that annoy me alot, because fixing an issue without understanding it is not how it should work. but at least now it works.

Open MSQL procedure from C# application (using System.Diagnostics)

I am having difficulties in finding a solution for opening a stored procedure straight to MSQL management studio for modifying in a new SQLQuery from my C# application (winform).
Here is my code:
Process openSQL = new Process();
openSQL.StartInfo.FileName = "Ssms.exe";
openSQL.StartInfo.Arguments = "dbo.getResults"; //name of the stored procedure I want to open
openSQL.Start();
I am getting error after executing the code :"The following files were specified on the command line: dbo.getResults These files could not be found and will not be loaded."
How am I supposed to "point" to the stored procedure in C# and get its definition displayed and ready to get modifications in MSQL management studio?
This isn't possible I'm afraid. If you run ssms -? from the command line you can see all the parameters that you can pass in:
Some options:
Let users edit procs themselves. After all, anyone capable of doing this will understand how to use SSMS properly.
Make your own UI. You can read the contents of a stored procedure and display them in a text box. The downside is that you lose features such as syntax highlighting (unless you also build that in too)
You could download the procedure and store it in a procedure.sql file and get SSMS to open that. Don't forget to pass in the server, database and credentials.
I found a way to open a stored procedure script straight to MSQL management studio for modifying in a new SQLQuery from my C# application (winform).
I am taking the script of the procedure with EXEC sp_helptext 'procedure_name'
The result set is filled in a DataSet
And the DataSet is getting written in an empty .sql file
The .sql file is getting opened in MSQL Managment Studio with System.Diagnostics;
Here are the steps with code snippets:
private void saveProcToAFile()
{
StreamWriter log;
if (!File.Exists("procedureToBeLoaded.sql"))
{
log = new StreamWriter("procedureToBeLoaded.sql");
}
else
{
log = new StreamWriter(File.Create("procedureToBeLoaded.sql"));
}
SqlConnection conn = new SqlConnection(conString);
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = string.Format("EXEC sp_helptext '{0}'", "procedure_name"); //Step 1.
da.SelectCommand = cmd;
DataSet ds = new DataSet();
conn.Open();
da.Fill(ds); //Step 2.
conn.Close();
foreach (DataRow dr in ds.Tables[0].Rows)
{
log.WriteLine(dr[0]); //Step 3.
}
log.Close();
}
Step 4.
private void contextMenuStripOpenInSqlStudio_Click(object sender, EventArgs e)
{
saveProcToAFile();
Process openSQL = new Process();
openSQL.StartInfo.FileName = "Ssms.exe";
openSQL.StartInfo.Arguments = "procedureToBeLoaded.sql";
openSQL.Start();
}

Running a t-sql stored procedure with EXECUTE AS statement with .NET SqlCommand

I have a .NET web service application that executes parameterized MS SQL Server stored procedures using System.Data.SqlCommand. The application receives a name of the stored procedure and its parameters from user input.
Also the application deployed within Windows AD domain and it is able to obtain the name of a remote user with the help of SSPI authentication.
using (var con = new SqlConnection(connectionString)) {
using (var cmd = new SqlCommand(procedureName, con)) {
cmd.CommandType = CommandType.StoredProcedure;
foreach (var pair in pairs.AllKeys) {
cmd.Parameters.Add(new SqlParameter(pair, pairs[pair]));
}
con.Open();
using (var reader = cmd.ExecuteReader()) {
// processing results
}
}
}
Now I want to execute a stored procedure with an EXECUTE AS statement.
use [db]
go
execute as user = 'domain\user' --execute as RemoteUser
exec [db].[stored_procdure] #param1=value1
Can this be done? How can I add EXECUTE AS to the SqlCommand?
I would not like to resort to sql injection prone code and build the sql request from strings received from user.
Solved it some time ago with a colleague of mine.
To achieve the requested behavior the execute as statement should be run in a separate preceeding SqlCommand while in the same SqlConnection.
After the closing of the reader, still in the same SqlConnection, there's another separate SqlCommand needed - revert - to switch back the context.
I was having a similar issue where I was able to Execute as User but the Revert wasn't working. By following prot's answer I was able to fix it. So for anyone having a similar issue this is how the code looks
SqlCommand cmd = new SqlCommand("EXECUTE AS USER = 'domain\\user';");
OSSDBDataContext dc = new OSSDBDataContext();
cmd.Connection = dc.Connection as SqlConnection;
cmd.Connection.Open();
cmd.ExecuteNonQuery();
//Execute stored procedure code goes here
SqlCommand cmd2 = new SqlCommand("REVERT;");
cmd2.Connection = dc.Connection as SqlConnection;
cmd2.ExecuteNonQuery();

Informix database via odbc connection - Issue with insert stored procedure

This stored proc. - SP_insertinfo inserts an entry into a table.
I am connecting via an ODBC DSN to an informix database.
This is my code, this one doesn't throw me an error or doesn't insert a record.
I am connected via sequeLink 3.10 32-bit driver, my application runs on 64-bit OS.
Trying to identify why the data is not getting inserted(when i put a breakpoint, get the parameterized statement into the actual DB, there it inserts for the same data, however it fails when run from the application code).
int rowsInserted = command.ExecuteNonQuery(); //This line is always
returning -1 and data doesn't get inserted.
Any thoughts/idea will be very much helpful?
private void InsertInfo()
{
try
{
using(var connection = new OdbcConnection("dsn=mydsn;UID=myusername;PWD=****;"))
{
var command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.Connection = connection;
command.CommandText = "execute procedure SP_insertinfo(?,?)";
command.Parameters.Clear();
//Insert parameter values
var paramId = new OdbcParameter("ID", OdbcType.Int) { Value = Convert.ToInt32(txtID.Text.Trim()) };
command.Parameters.Add(paramId);
var paramCountry = new OdbcParameter("Country", OdbcType.VarChar, 25) { Value = txtCountry.Text.Trim() };
command.Parameters.Add(paramCountry);
connection.Open();
int rowsInserted = command.ExecuteNonQuery(); //This line is always returning -1 and data doesn't get inserted.
if (rowsInserted > 0)
{
MessageBox.Show("Insert data saved.");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString()) ;
}
}
At first try to execute your procedure as simple statement, not as prepared statement. This will look like:
command.CommandText = "execute procedure SP_insertinfo(1, 'Poland')";
connection.Open();
int rowsInserted = command.ExecuteNonQuery();
This way you will see if it is problem with prepared statement.
Try to execute execute procedure SP_insertinfo(1, 'Poland') via dbaccess (Informix tool). This way you will see if it is ODBC issue.
If it do not work with dbaccess then you will have to debug SP_insertinfo. If it work, then problem is with ODBC. Then I suggest enabling ODBC trace in ODBC Manager and analyzing log it will produce.
After a long research, i found out that, in order for ODBC dsn to work correctly with sequeLink, the drivers should match the version of operating system, i am using windows 7.0 64-bit, my dsn was 32-bit , i used a 64-bit dsn in order to work with 64-bit OS.

what is wrong in my code to call a stored procedure

I Have created a Stored procedure dbo.test as follows
use sample
go
create procedure dbo.test as
DECLARE #command as varchar(1000), #i int
SET #i = 0
WHILE #i < 5
BEGIN
Print 'I VALUE ' +CONVERT(varchar(20),#i)
SET #i = #i + 1
END
Now i am created a c# console application to call the stored procedure as follows
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace AutomationApp
{
class Program
{
public void RunStoredProc()
{
SqlConnection conn = null;
SqlDataReader rdr = null;
try
{
conn = new SqlConnection("Server=(TEST\\SQL2K5EXPRESS);DataBase=sample,IntegratedSecurity=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand("sample.dbo.test", conn);
cmd.CommandType = CommandType.StoredProcedure;
//cmd.ExecuteNonQuery();
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
rdr[0], rdr[1]));
}
}
catch(Exception ex)
{
Console.writeLine(ex.message);
}
finally
{
if (conn != null)
{
conn.Close();
}
if (rdr != null)
{
rdr.Close();
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World");
Program p= new Program();
p.RunStoredProc();
Console.Read();
}
}
}
O/P:
Hello World
//Could not find stored procedure 'test'.
A network-related or instance-specific error occurred while establishing a conne
ction to SQL Server. The server was not found or was not accessible. Verify that
the instance name is correct and that SQL Server is configured to allow remote
connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Serve
r/Instance Specified)
But when i try to run the program it was closing so i debugged the program then at exactly at executeReader() method it was showed that can not find the stored procedure "dbo.test"
and when i give the "EXEC dbo.test" at SSMS it display the result as i expected.
waht is wronng with this any Help greatly Appreciated.
Why are you looking in the master database?
Also, your code needed some cleanup:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace AutomationApp
{
class Program
{
public void RunStoredProc()
{
Console.WriteLine("\nTop 10 Most Expensive Products:\n");
using (SqlConnection conn =
new SqlConnection(
"Server=(local);DataBase=master;IntegratedSecurity=SSPI"))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("dbo.test", conn) {
CommandType = CommandType.StoredProcedure})
{
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
rdr[0], rdr[1]));
}
}
}
}
}
}
}
I would suggest it is related to teh permissions granted to the stored procedure.
Check out "GRANT EXECUTE <storedProc> TO <User>" you could also check the permissions in SSMS by right clicking on the stored proc.
I understand this is a test stored proc but it is not optimal to create stored procedures in the master database.
All the best :)
Just change your connection string:
conn = new SqlConnection("Server=(local);DataBase=master;IntegratedSecurity=SSPI");
You're hitting the master database. You want to hit whatever your database is called.
Alternatively, call the stored proc as dbname.dbo.test.
First of all - there's typo in your connection string - you need to use all semicolons - not semicolon once and commas the other time. Between DAtaBase= and IntegratedSEcurity, you have a comma - plus, it has to be "Integrated Security" (with a space!). Check out www.connectionstrings.com for the details on how to properly create a connection string.
Your original connection string in your post:
conn = new SqlConnection(
"Server=(TEST\\SQL2K5EXPRESS);DataBase=sample,IntegratedSecurity=SSPI");
should really be:
conn = new SqlConnection(
"Server=(TEST\\SQL2K5EXPRESS);DataBase=sample;Integrated Security=SSPI");
Once that would work, I think the main problem is that you're trying to pass in a SQL statement in the parameter #command to the stored procedure, which you execute inside the stored procedure (not in your current post, but in others you've posted), and you want to read out the rows returned by that statement.
But you have no way of being sure (short of parsing the SQL statement you're passing in) whether or not that SQL statement will actually indeed return values or whether it's a DDL statement like INSERT, CREATE TABLE or something.
So you have ADO.NET, calling a stored proc, which dynamically executes an arbitrary SQL statement, and you still want to be able to retrieve those results....
In my opinion, you need to rearchitect your approach - this will never work reliably - find another way to do what you're trying to do - there must be a way to do this with less dynamic execution of SQL inside a stored proc and stuff........ there's gotta be an easier way!
Marc
Have you tried just using "test" instead of "dbo.test"?
Your stored procedure doesn't return any results. Change your PRINT into SELECT.
You may be getting the error because ADO.NET doesn't know how to react to the status messages the print statement causes.
The SQL error you see is connecting to the server. It doesn't even get that far, so it isn't related to permissions at all. As far as your client goes, you'd get the same error if you connected to "Server=GroverCleveland\Instance1" (assuming it doesn't exist on your network).
I think that the problem is that you are wrapping the server name in parens, if you can connect to it fine using other SQL clients on the same client box. Try the following:
conn = new SqlConnection("Server=TEST\\SQL2K5EXPRESS;DataBase=sample;IntegratedSecurity=SSPI");
Marc is right about the semicolon, btw. Check out connectionstrings.com for details on that...

Categories

Resources