How to get the executing SQL query from a table adapter? [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get the generated SQL-Statement from a SqlCommand-Object?
I would like to know how to retrieve the SQL query that was executed by a Table Adapter for logging purposes.
For example:
Input:
RandomTableAdapter tableAdapter = new RandomTableAdapter();
tableAdapter.Insert("val","val","val","val");
Output:
What I would like to log is the insert statement, which is generated by the table adapter in order to execute the insert command.
Insert INTO RandomTable VALUES ('val', 'val', 'val', 'val');
How can I do this? Does anyone have any suggestions regarding this?

You can use this workaround with replace ParameterName with its value
but it not good because you need to manage value formatting by your own, and it can be slow
and you will need to get parameters after Insert is executed
code:
var usersTableAdapter = new testDataSetTableAdapters.usersTableAdapter();
usersTableAdapter.Insert(4, "home", "origin", "email#host.com", "realname", "spec", 1, "username", "usernick", "whereform");
var cmd = usersTableAdapter.Adapter.InsertCommand;
var text = cmd.CommandText;
var sb = new StringBuilder(text);
foreach (SqlParameter cmdParam in cmd.Parameters)
{
if (cmdParam.Value is string)
sb.Replace(cmdParam.ParameterName, string.Format("'{0}'", cmdParam.Value));
else
sb.Replace(cmdParam.ParameterName, cmdParam.Value.ToString());
}
Console.WriteLine(sb.ToString());

Related

SQL paramaterization WHERE IN not working [duplicate]

This question already has answers here:
Pass Array Parameter in SqlCommand
(11 answers)
Closed 5 months ago.
I have a specific question about the WHERE IN command inside of a parameterized sql query.
Current situation
All the normal queries are working, but on the following query example it goes wrong:
SELECT * FROM table WHERE Id IN(#Ids)
What does this query do?
This query is selecting all items in the table with the specific ids.
The error
# this generates the following string: "1,2,3,4", which gets parsed into the #Ids param
new OleDbParameter("Ids", String.Join(",", objects.Select(c => c.Id.ToString())));
This will generate the folling raw sql query:
# this is the converted sql query after performing the OleDbCommand.ExecuteNonQueryAsync()
# which is not working
SELECT * FROM table WHERE Id IN("1,2,3,4")
# this is the sql query that is working
SELECT * FROM table where Id IN("1", "2", "3", "4")
solution
as you can see, the first example is an array, but is not an array inside of the IN statement. How can I change my code so it will get the working sql query with parameterization?
You could try this
var ids = new char[objects.Count()];
Array.ForEach(ids, x => x = '?');
var idsList = string.Join(',', ids);
var queryString = $"SELECT * FROM table WHERE Id IN ({idsList})";
var command = new OleDbCommand(queryString, connection);
for (int i = 0; i < ids.Length; i++)
{
command.Parameters.Add($"#p{i + 1}", OleDbType.VarChar, 5).Value = objects.ElementAt(i).Id;
}
OleDbDataReader reader = command.ExecuteReader();

Multiple SQL query in C# [duplicate]

This question already has answers here:
How to run multiple SQL commands in a single SQL connection?
(9 answers)
How do I return multiple result sets with SqlCommand?
(7 answers)
Closed 5 years ago.
I'm having trouble to figure out how to get more then one SQL query to work in C#. I have something like this:
breakControlq.CommandText =
#"SELECT something as q1 From table" +
"SELECT somethingelse as q2 FROM table where this = this";
breakControlq.CommandType = CommandType.Text;
breakControlq.Connection = hd01Connect;
try
{
hd01Connect.Open();
breakControlRead = breakControlq.ExecuteReader();
while (breakControlRead.Read())
{
textBox1.AppendText(breakControlRead["q1"].ToString());
textBox2.AppendText(breakControlRead["q2"].ToString());
}
catch(System.Data.SqlClient.SqlException ex)
{
MessageBox.Show(ex.Message, "Connection Error");
}
Is this possible to do?
Do I have to repeat the connection/command to every single query?
I'm pretty new at this and some of you will tell that this has already been answered somewhere, but I searched so many posts that I'm more confused then when a started to search for the solution.
You are looking for .NextResult(). The .Read() method changes to the next row in the current grid; .NextResult() moves to the next grid:
while (breakControlRead.Read())
{
// process rows from first grid
}
if(breakControlRead.NextResult()) {
while (breakControlRead.Read())
{
// process rows from second grid
}
}
Alternatively; "dapper" would expose this via .QueryMultiple():
using(var multi = conn.QueryMultiple(sql, args)) {
var s = multi.Read<string>().AsList(); // items from first grid
var i = multi.ReadSingle<int>(); // items from second grid
// ...
}
Note! You do need to ensure that your two queries are separated by either whitespace or ;; in your case this would be fine:
#"SELECT something as q1 From table
SELECT somethingelse as q2 FROM table where this = this";
(note whitespace)
alternative and more correctly:
#"SELECT something as q1 From table;
SELECT somethingelse as q2 FROM table where this = this;";
or:
#"SELECT something as q1 From table;SELECT somethingelse as q2 FROM table where this = this;";
I'm having trouble to figure out how to get more then one SQL query to
work in C#
Well, wrap both your SQL statement in a stored procedure and call that procedure from your application code like
create procedure usp_data
as
begin
SELECT something as q1 From table;
SELECT somethingelse as q2 FROM table where this = this;
end
See How to: Execute a Stored Procedure that Returns Rows for more information

How can I count the number of tables in C# [duplicate]

This question already has answers here:
Retrieve List of Tables from Specific Database on Server C#
(7 answers)
Closed 7 years ago.
How can I make a code to get the number of tables to a link textbox in a given database? I'm using visual studio 2013 and I'm new to this. I used database server ms sql.
public static List<string> GetTables(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
DataTable schema = connection.GetSchema("Tables");
List<string> TableNames = new List<string>();
foreach (DataRow row in schema.Rows)
{
TableNames.Add(row[0].ToString());
}
return TableNames;
}
}
To be honest, i don't understand the question. You want the count of tables in a given database. The database is specified by the connection-string. You have already the code that returns a DataTable with all tables.
So here is the missing piece. Since connection.GetSchema("Tables") also returns views, if you want to count both you are ready with:
DataTable schema = connection.GetSchema("Tables");
int tableAndViewCount = schema.Rows.Count;
If you only want to count tables and exclude views:
int tableCount = schema.AsEnumerable().Count(t => t.Field<string>("TABLE_TYPE") == "BASE TABLE");
Get count of tables using the below query , just add that query in your application.
SELECT COUNT(*) from information_schema.tables
WHERE table_type = 'base table'
Try this Query
select * from sys.tables

Get used tables from sql query [duplicate]

This question already has answers here:
List of tables used in an SQL Query
(5 answers)
Closed 9 years ago.
I need extract from simple string that represent an sql query the tables that are used on the query without execute the query itself in C#.
Example:
string strQuery = "SELECT * FROM table1 LEFT JOIN (SELECT * FROM table2) tt WHERE tt.name IN (SELECT name FROM table3)";
ArrayList arrUsedTables = GetUsedTablesFromQuery(strQuery);
and after this line the object arrUsedTables would contain:
table1,table2,table3
Remember that the query may be much complicated!
Without going to the DB you can't know for certain the names of the tables used in the query.
What if your query uses a view or a stored procedure?
Without consulting the database, these are transparent to the consumer.
The only way to be certain is to query the list of the tables from the database and then to attempt to parse them from your inline sql.
You will have to add references and directives for the following assemblies:
using Microsoft.Data.Schema.ScriptDom;
using Microsoft.Data.Schema.ScriptDom.Sql;
using System.IO;
Then, you may create the GetUsedTablesFromQuery method:
private static ArrayList GetUsedTablesFromQuery(string strQuery)
{
var parser = new TSql100Parser(true);
IList<ParseError> errors = new List<ParseError>();
using (TextReader r = new StringReader(strQuery))
{
var result = parser.GetTokenStream(r, out errors);
var tables = result
.Select((i, index) => (i.TokenType == TSqlTokenType.From) ? result[index + 2].Text : null)
.Where(i => i != null)
.ToArray();
return new ArrayList(tables);
}
}
You can certainly use a SQL parser such as ANTLR, as described in this question and answer, in order to get a full parse of the SQL, and then extract the table names.
Another option is to execute some raw SQL to get the execution plan of the query (using the instructions here). The execution plan is in XML, and then you can use Linq to XML to query the plan for all Table attributes on any ColumnReference tag.

Can't change sql server file database size [duplicate]

This question already has answers here:
How to use a variable for the database name in T-SQL?
(4 answers)
Closed 10 years ago.
I can't change the database file size with a C# query. For some reason I get an exception: "Incorrect syntax near '#databaseName'.
This is the code that executed the query:
command = connection.CreateCommand();
command.CommandText = #"
ALTER DATABASE #databaseName
MODIFY FILE
(NAME = #databaseFile, SIZE = #newSize)
";
dbParam = command.CreateParameter();
dbParam.ParameterName = "databaseFile";
dbParam.Value = dbFileName;
command.Parameters.Add(dbParam);
dbParam = command.CreateParameter();
dbParam.ParameterName = "newSize";
dbParam.Value = newSize;
command.Parameters.Add(dbParam);
dbParam = command.CreateParameter();
dbParam.ParameterName = "databaseName";
dbParam.Value = databaseName;
command.Parameters.Add(dbParam);
command.ExecuteNonQuery();
Now there might be several problems. Firstly the database is on a different machine so wouldn't the db file path be different?
Some things cannot be parameterized. That includes things like table and column names in DML, but includes most of DDL. It is not expecting, and cannot process, parameters in this scenario.
To check this; just run it in SSMS, declaring the variables ahead of time and giving them values. You will find the error message is the same. If it doesn't work in SSMS it is very unlikely to work from ADO.NET.

Categories