mysql select command in C# with dynamic column names - c#

I have a string in C# which has the column names of a table as shown below
shown_itemsName = "billno,department,date,subtotal,tea,coffee";
I want to display a table in dataGridView with column names that are there in the string (shown_itemsName) but when i write sql query
cmdDataBase.CommandText = "select #shown_itemsName from employee.transaction where department = #department AND MONTH(date) = #month_ AND YEAR(date) = #year_";
cmdDataBase.Parameters.AddWithValue("#shown_itemsName", shown_itemsName);
cmdDataBase.Parameters.AddWithValue("#department", this.department.Text);
cmdDataBase.Parameters.AddWithValue("#month_", this.dateTimePicker1.Value.Month);
cmdDataBase.Parameters.AddWithValue("#year_", this.dateTimePicker1.Value.Year);
I get a table with only 1 column and 4 rows with the cell value as billno,department,date,subtotal,tea,coffee and the heading of that column also the same string.
Whereas I should be getting 6 columns and 4 rows as the result with the "," separated substrings as the column names

You cannot add new columns with parameters. If it is dynamic you don't have a choice but writing your query every time and execute a CommandType.Text command on it.
For every request, you must:
cmdDataBase.CommandText = "select " + shown_itemsName + " from employee.transaction where department = #department AND MONTH(date) = #month_ AND YEAR(date) = #year_";
cmdDataBase.Parameters.AddWithValue("#department", this.department.Text);
cmdDataBase.Parameters.AddWithValue("#month_", this.dateTimePicker1.Value.Month);
cmdDataBase.Parameters.AddWithValue("#year_", this.dateTimePicker1.Value.Year);
using(var reader = cmdDataBase.ExecuteReader()) {
while(reader.Read()) {
// ...
}
reader.Close();
}

Related

How to get specific element in foreach loop in c#?

I have a list and I need to update some of the data in this list.
I have a update T-SQL query:
Update Report
Set ['+#Period+'] = #Amount
Where Group = 1
I think that I can use foreach for this update.
string period=startDate.ToString("yy/MM/dd").Substring(0, 2) + startDate.ToString("yy/MM/dd").Substring(3, 2);
foreach (var item in report)
{
if (item.Grup == 1)
{
item.??? = amount; //My period names in the table like _2101, _2102 etc
}
}
I use foreach because I have a while condition outside of the foreach and the update operation will occur for other periods. How can I get the item.period?
--Edit--
My table looks like that and I want to update null values one by one. This method returns the report table.
It's not a good idea to store periods in columns as such if you're planning to add more. It would be easier to change your table structure so that it can support having its own table for periods.
But if for some reasons you really have to do it. You could get these columns name using the following t-sql (assuming your table is on the [dbo] schema and the columns you need all start with an underscore) :
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Report' AND TABLE_SCHEMA='dbo' AND COLUMN_NAME LIKE '\_%' ESCAPE '\'
Then using these column names you could build a new query with these column names :
"SELECT " + string.Join(',', columnNames) + " FROM Report"
using Dapper you could do the following :
IEnumerable<string> columnNames;
using (var connection = new SqlConnection(dbConnectionString))
{
columnNames = connection.Query<string>(#"
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Report' AND TABLE_SCHEMA='dbo' AND COLUMN_NAME LIKE '\_%' ESCAPE '\'");
}
IEnumerable<dynamic> reports;
using (var connection = new SqlConnection(dbConnectionString))
{
reports = connection.Query("SELECT " + string.Join(',', columnNames) + " FROM Report");
}
foreach(var report in reports)
{
report._2021 = (object)1.0;
}
This way you can access the values of _2101, _2102, etc.
But creating a period table to store these would make 100% more sense.

How to extract an enumerable datatable from database when column names and count may vary?

How do I extract data from a data table in a sql server database, knowing that the table could have different column names/column count depending on the request?
I would usually use a SqlDataAdapter and then do: da.Fill(dt) but this is not an option as I cannot enumerate through a dataTable in a razor view. I wish to reproduce that table in a view using Razor Pages.
Here is an example of what I might normally do, but it involves knowing exactly what the column names will be and how many there will be. What can I put in the while to return all of the table data in a type that is enumerable?:
SqlConnection connectionCalc = new SqlConnection("<connectionString>");
if (connectionCalc.State.Equals(ConnectionState.Closed))
connectionCalc.Open();
using (var command = connectionCalc.CreateCommand())
{
command.CommandText = $#"SELECT * FROM {tableName}";
SqlDataReader reader = command.ExecuteReader();
column = new Dictionary<string, string>();
int FATUidSingle = -999;
while (reader.Read())
{
TableUid.Add(reader[SelectedCalculation + "TABLE_UID"].ToString());
FATUid.Add(Convert.ToInt32(reader["FAT_UID"]));
ScheduledDate.Add(Convert.ToDateTime(reader["SOME_DATE"]));
TableStatusUid.Add(reader[SelectedCalculation + "ST_UID"].ToString());
StartDate.Add(Convert.ToDateTime(reader["ANOTHER_DATE"]));
EndDate.Add(Convert.ToDateTime(reader["OTHER_DATE"]));
Progress.Add(reader["PROGRESS"].ToString());
}
Run a command like this first to get the field names, then you will know which fields to expect. You could use it to build SQL and set ordinals to point to the column you want
SELECT TABLE_NAME, COLUMN_NAME FROM
INFORMATION_SCHEMA.COLUMNS
where table_name = 'EmployeeDetail'
when you make your enumerable list, make a list of 'tuples' of string and object perhaps, where the string is the field name and the object is the value
If you only worry about exact names but you know column sequence and datatype then you could simply rely on index of column from select statement.
E.g
Select * from Orders
Order table might have 3 columns. Id, Name and Price where id is int, Name is string and Price is long.
So you can do:
var id = reader.GetInt32(0);
var name = reader.GetString(1);
var price = reader.GetInt64(2);

C# {"ORA-00917: missing comma"} INSERT QUERY ERROR

I am trying to insert these values:
int limit = 50000;
int acc_id = 1;
string query = "INSERT INTO CURRENT_ACCOUNT(C-ACCOUNT_NO,DAILY_LIMIT)
VALUES ('"+acc_id+"','"+limit+"')";
OracleCommand command = new OracleCommand(query, con);
command.ExecuteNonQuery();
But getting a missing comma exception:
C# {"ORA-00917: missing comma"}
Are you sure your CURRENT_ACCOUNT table contains a column with the name C-ACCOUNT_NO? Is the column named C_ACCOUNT_NO (with the dash - replaced with an underscore _) instead?
If the column name genuinely does contain a dash, wrap the column name in double-quotes:
string query = "INSERT INTO CURRENT_ACCOUNT(\"C-ACCOUNT_NO\",DAILY_LIMIT) " + // ...
You have to add semicolon at the end of query..
string query = "INSERT INTO CURRENT_ACCOUNT(C-ACCOUNT_NO,DAILY_LIMIT)
VALUES ("+acc_id+","+limit+");";

Insert multiple rows from another table and get the IDs of inserted rows in SQL Server 2000

I have table A and table B, table B has the same columns of A and only one extra column x , I want to insert some rows from A to B , and then I want to update each one of these last inserted rows with a new value for column x.
How can I do it in SQL Server 2000?
Now I am using this query in C# code, I select all wanted rows from A and I save it in DataTable
string Query = "Select * from A where ID = 5";
SqlDataAdapter dap = new SqlDataAdapter(Query, Conn);
dap.Fill(DataTablle1);
foreach (DataRow row in DataTablle1.Rows)
{
string query2 = "Insert into B (col a , col b, col x) values ('" + row["col a"] + "','" + row["col b"] + "',3)";
}
This way requires many insert statement depending on the number of rows in table A, is there any way to achieve it with minimum number of insert statement?
You could just have an insert-select statement with the literal 3:
INSERT INTO b ([col a] , [col b], [col x])
SELECT [col a], [col b], 3
FROM a
WHERE id = 5

What method can be used to specifically insert data into your C# DataGridView from SQL?

Problem:
Code works fine, however, when I launch my program my two predefined columns Course_ID and File_Count are present in my then blank dataGridView. There is also an empty default row.
Whenever I run my query, my dataGridView is getting an extra column created and an extra row created. The result from the query goes into this new third column on the first row which is weird.
See here:
http://imgur.com/UBFI8Nz
Here is my code:
string[] courses = txtBoxCourses.Text.Split(',');
SqlConnection myConnection = new SqlConnection("user id=userid;" +
"password=password;server=myserver;" +
"Trusted_Connection=no;" +
"connection timeout=30");
myConnection.Open();
SqlCommand myCommand = new SqlCommand();
SqlDataAdapter adapter = new SqlDataAdapter(myCommand);
myCommand.Connection = myConnection;
DataTable t = new DataTable();
foreach (string line in courses)
{
myCommand.CommandText = "DECLARE #CourseName varchar(80); Set #CourseName = '"+line+"' SELECT COUNT(*) FROM ( SELECT FILE_ID,PARENT_ID ,PATH_ID,FULL_PATH ,FILE_NAME FROM BBLEARN_cms_doc.dbo.XYF_URLS WHERE FULL_PATH like '/courses/'+#CourseName+'/%') as subquery;";
adapter.Fill(t);
dataGridView1.DataSource = t;
}
What I want to happen is I want to fill in the first column with the values from my string[] courses list and I want it to correspond with the result from the query in my foreach statement. For example, if I use two course IDs to query, test1 and test2 I'd prefer this:
Course_ID file_count
test1 234
test2 1478
I've looked into using the DataPropertyName property but I don't think that's it.
Try changing your select to:
SELECT #CourseName as Course_ID, COUNT(*) as File_Count FROM (
SELECT FILE_ID,PARENT_ID ,PATH_ID,FULL_PATH ,FILE_NAME FROM BBLEARN_cms_doc.dbo.XYF_URLS
WHERE FULL_PATH like '/courses/'+#CourseName+'/%') as subquery;
Your current query is returning an integer and your grid view doesn't see it attached to any of your predefined columns. Try aliasing the columns with the column name in the grid view. That should tie your sql results to your current columns.

Categories