Need sql for creating view set in asp.net c# - c#

I am using sqlconnection. I want to create a view and select from the view set.
Like I have shown below I have created a view called vwtopic.. from this I need to select distinct values of a column.
I cannot put in one easy statment because i need distinct values of topic column only and need to order by another column datetime..
So I am first creating a view where I am ordering by datetime and from this I am selecting distinct topic.
Problem is I am able to create a view set, but from this I am not able to select the distinct topic data to a SqlDataAdapter.. I frankly dont know the syntax.. I have not tried this before..
First part:
SqlConnection con = new SqlConnection("server=xxxx;database=wbsd;user id=***;password=***;");
SqlCommand add = new SqlCommand("CREATE VIEW vwtopic AS SELECT * FROM sr_topic_comment ORDER BY datetime DESC", con);
try
{
add.Connection.Open();
add.ExecuteNonQuery();
add.Connection.Close();
}
catch (System.FormatException)
{
}
Second part:
String sqlcmd = "SELECT DISTINCT topic FROM vwtopic WHERE owner='" + owner + "'";
SqlDataAdapter adap = new SqlDataAdapter(sqlcmd,con);

Instead of creating Views in Code, use the "WITH" statement or Sub-queries this should meets your needs:
WITH [vwtopic] AS (
SELECT * -- I recommend using each column name
FROM [sr_topic_comment]
-- not sure if ORDER BY is allowed here:
-- ORDER BY [datetime] DESC
)
SELECT DISTINCT [topic] FROM [vwtopic] -- add WHERE, ORDER BY

Since the view you are creating does not have any filters defined, selecting distinct values from the view is equivalent to selecting distinct values from the table. When selecting distinct values, you can only order by those values (not the datetime column as you're attempting here). Therefore, you can do:
SqlCommand cmd = new SqlCommand("SELECT DISTINCT topic FROM sr_topic_comment WHERE owner = #owner", con);
cmd.Parameters.Add(new SqlParameter(#owner, SqlDbType.Varchar, 25));
cmd.Parameters["#owner"].Value = owner;
DataSet ds = new DataSet();
using (SqlDataAdapter adap = new SqlDataAdapter(cmd)) {
adap.Fill(ds);
}
This will give you a DataSet filled with the distinct values from the table that meet the filter criteria (owner == the supplied owner).

I found the answer below will do the trick for me...
I am filling the result in dataset and calling my required column 'topic'..
SELECT DISTINCT topic,datetime FROM sr_topic_comment WHERE owner='sr' ORDER BY datetime DESC
Thank you very much for your inputs.. I learnt about WITH clause today.. cheers..

Related

How to read 1 record from a sql server database into a c# textbox?

I want to do this (on Form3):
sqlcon.Open();
string selectQuery = "SELECT * FROM InvoiceTable where id = #id";
SqlCommand sqlcmd = new SqlCommand(selectQuery, sqlcon);
sqldr = sqlcmd.ExecuteReader();
while(sqldr.Read())
{
textbox1 = Max value of TotalCostColumn.value
or
textbox1 = Latest value of TotalCostColumn.value
or
textbox1 = 2nd row of TotalCostColumn.value
}
Im not having any datagridview on this form. I do have a datagridview on Form1 which is the actual invoice form. Form3 is the confrimation form which lets the user confirm how much customer should pay eventually. I want the TotalCostColumn's value from my database to be transfered in the related textbox in Form3.
textbox1 = Max value of TotalCostColumn.value
If that's your requirement then why not build the query as per like
SELECT max(TotalCostColumn) FROM InvoiceTable where id = #id
And then instead of using ExecuteReader() you should call ExecuteScalar() which would return a single value
This is how you'd get the Max value with ExecuteScalar:
string selectQuery = "SELECT MAX(TotalCostColumn) FROM InvoiceTable where id = #id";
var sqlcmd = new SqlCommand(selectQuery, sqlcon);
var result = sqlcmd.ExecuteScalar();
return int.Parse(result.ToString());
MAX will ensure you only get one row from the table.
To get the latest value, you'd have to sort the table (I assume there's a transaction date) and add TOP 1 to get only the first row. (Although ExecuteScalar will ignore everything except the first field of the top row but there's no point returning data you don't need)
There are two ways to get the second row. One is to use a datareader and skip over the first row. The other is with SQL:
SELECT TOP 1 FROM
(
SELECT TOP 2 TotalCost FROM InvoiceTable where id = #id ORDER BY TotalCost DESC
) ORDER BY TotalCost ASC
Here the inner query gets two rows of data sorted with the largest item first, and the outer query picks the lower value of the two.
You need to write a stored procedure which accepts the value of the id
stored procedure is defined as follows
create proc selectmax(#id int)
as begin
select max(TotalCostColumn) FROM InvoiceTable where id = #id
end
and call it as below using Disconnected Model so sqlcon.open() is not Required
SqlCommand sqlcmd = new SqlCommand(selectmax, sqlcon);
sqlcmd.CommandType=CommandType.StoredProcedure
SqlDataAdapter adapter= new SqlDataAdapter(sqlcmd);
DataSet value=new DataSet();
adapter.Fill(value);
This is the implementation using Ado.net Disconnected Model

SQL Server - Update table and return the Updated rows

I have a SQL Server database which has a lot of information inside.
I want to select top 50 rows in a single query (which I did, with no problem) but then I want to update a column from false to true, so next time I select I wont select the same, my code looks like this:
string Command = "UPDATE HubCommands SET [Alreadytaken] = 'true' FROM (SELECT TOP 50 [CommandId],[DeviceId],[Commandtext], [HashCommand],[UserId] FROM HubCommands) I WHERE [HubId] = '18353fe9-82fd-4ac2-a078-51c199d9072b'";
using (SqlConnection myConnection = new SqlConnection(SqlConnection))
{
using (SqlDataAdapter myDataAdapter = new SqlDataAdapter(Command, myConnection))
{
DataTable dtResult = new DataTable();
myDataAdapter.Fill(dtResult);
foreach (DataRow row in dtResult.Rows)
{
Guid CommandId, DeviceId, UserId;
Guid.TryParse(row["CommandId"].ToString(), out CommandId);
Guid.TryParse(row["DeviceId"].ToString(), out DeviceId);
Guid.TryParse(row["UserId"].ToString(), out UserId);
Console.WriteLine("CommandId" + CommandId);
}
}
}
This code does work, and it updates what I ask it to update, but I don't get nothing in the data table, its like it is always updating but not selecting.
If I do a normal select it does work and give information.
Does anyone have any idea how to update and get some data back, in a single query?
So your question is:
How can I update a table in SQL Server using C# and return the truly updated
rows as a DataTable ?
First You have multiple issues in your query.
You should use 1 and 0, not true or false. SQL-Server has a bit datatype and not a Boolean.
Second, this is how you should've constructed your query:
DECLARE #IDs TABLE
(
[CommandId] uniqueidentifier
);
INSERT INTO #IDs
SELECT [CommandId] FROM HubCommands
WHERE [HubId] = '18353fe9-82fd-4ac2-a078-51c199d9072b' AND [Alreadytaken] = 0;
UPDATE HubCommands
SET [Alreadytaken] = 1
WHERE CommandId IN
(
SELECT [CommandId] FROM #IDs
);
SELECT * FROM HubCommands
WHERE CommandId IN
(
SELECT [CommandId] FROM #IDs
);
Wrap all the above in a single string and use SqlDataReader. No need for an Adapter in you case (Since we're mixing commands unlike what the adapter usually does):
var sqlCommand = new SqlCommand(Command, myConnection);
SqlDataReader dataReader = sqlCommand.ExecuteReader();
DataTable dtResult = new DataTable();
dtResult.Load(dataReader);
I highly advise you to create a stored procedure accepting HubId as a parameter that does all the above work. It is neater and better for maintenance.

c# OleDB Doesn't update database [duplicate]

I have been trying to use OleDbDataAdapter to update a DataTable but got confused about the commands.
Since I sometimes get info from diffrent tables I can't use a CommandBuilder.
So I have tried to create the commands on my on but found it hard with the parameters.
DataTable.GetChanges returns rows that needs to use an INSERT or an UPDATE command - I guess I can't distinct between them.
I need you to complete the following:
DataTable dt = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter();
// Here I create the SELECT command and pass the connection.
da.Fill(dt);
// Here I make changes (INSERT/UPDATE) to the DataTable (by a DataGridView).
da.UpdateCommand = new OleDbCommand("UPDATE TABLE_NAME SET (COL1, COL2, ...) VALUES (#newVal1, #newVal2, ...) WHERE id=#id"); // How can I use the values of the current row (that the da is updating) as the parameters (#newVal1, #newVal2, id....)?
Thank you very much!
The data adapter can work in conjunction with the datatable. As such, I've actually wrapped mine together into a class and works quite well. Aside from the complexities of my stuff, here's a snippet that might help you along. When adding a parameter, you can identify the column source that the data is coming from FROM the DataTable. This way, when a record is internally identified as "Added" or "Updated" (or "Deleted"), when you build your SQL Insert/Update/Delete commands, it will pull the data from the columns from the respective rows.
For example. Say I have a DataTable, primary Key is "MyID" and has columns "ColX, ColY, ColZ". I create my DataAdapter and build out my select, update, delete commands something like... (? is a place-holder for the parameters)
DataAdapter myAdapter = new DataAdapter()
myAdapter.SelectCommand = new OleDbCommand();
myAdapter.InsertCommand = new OleDbCommand();
myAdapter.UpdateCommand = new OleDbCommand();
myAdapter.DeleteCommand = new OleDbCommand();
myAdapter.SelectCommand.CommandText = "select * from MyTable where MyID = ?";
myAdapter.InsertCommand.CommandText = "insert into MyTable ( ColX, ColY, ColZ ) values ( ?, ?, ? )";
myAdapter.UpdateCommand.CommandText = "update MyTable set ColX = ?, ColY = ?, ColZ = ? where MyID = ?";
myAdapter.DeleteCommand.CommandText = "delete from MyTable where MyID = ?";
Now, each has to have their respective "Parameters". The parameters have to be addded in the same sequence as their corresponding "?" place-holders.
// Although I'm putting in bogus values for preparing the parameters, its just for
// data type purposes. It does get changed through the data adapter when it applies the changes
OleDbParameter oParm = new OleDbParameter( "myID", -1 );
oParm.DbType = DbType.Int32;
oParm.SourceColumn = "myID"; // <- this is where it looks back to source table's column
oParm.ParameterName = "myID"; // just for consistency / readability reference
myAdapter.SelectCommand.Parameters.Add( oParm );
do similar for rest of parameters based on their types... char, int, double, whatever
Again, I have like a wrapper class that handles managment on a per-table basis... in brief
public myClassWrapper
{
protected DataTable myTable;
protected DataAdapter myAdapter;
... more ...
protected void SaveChanges()
{
}
}
Its more complex than just this, but during the "SaveChanges", The datatable and dataAdapter are in synch for their own purposes. Now, flushing the data. I check for the status of the table and then you can pass the entire table to the dataAdapter for update and it will cycle through all changed records and push respective changes. You'll have to trap for whatever possible data errors though.
myAdapter.Update( this.MyTable );
As it finds each "changed" record, it pulls the values from the Column Source as identified by the parameter that is found in the table being passed to the adapter for processing.
Hopefully this has given you a huge jump on what you are running into.
---- COMMENT PER FEEDBACK ----
I would put your update within a try/catch, and step into the program to see what the exception is. The message adn/or inner exception of the error might give more info. However, try to simplify your UPDATE to only include a FEW fields with the WHERE "Key" element.
Additionally, and I oopsed, missed this from first part answer. You might have to identify the datatable's "PrimaryKey" column. To do so, its a property of the DataTable that expects and array of columns that represent the primary key for the table. What I did was...
// set the primary key column of the table
DataColumn[] oCols = { myDataTbl.Columns["myID"] };
myDataTbl.PrimaryKey = oCols;
I would comment out your full update string and all its parameters for your UPDATE. Then, build it with just as simple as my sample of only setting 2-3 columns and the where clause
myAdapter.UpdateCommand.CommandText = "update MyTable set ColX = ?, ColY = ? where MyID=?";
Add Parameter object for "X"
Add Parameter object for "Y"
Add Parameter object for "MyID"
Pick fields like int or char so they have the least probability of problems for data type conversions, then, once that works, try adding all your "int" and "character" columns... then add any others. Also, which database are you going against. SOME databases don't use "?" as placeholder in the command but use "named" parameters, some using
"actualColumn = #namedCol"
or even
"actualColumn = :namedCol"
Hope this gets you over the hump...
You could use the String.Format Method to replace the #newVal1, #newVal2, ... in your code, like this da.UpdateCommand = new OleDbCommand(String.Format("UPDATE TABLE_NAME SET (COL1, COL2, ...) VALUES ({0}, {1}, ...) WHERE id=#id",OBJECT_ARRAY_CONTAINING_VALUES_FROM_THEDG));
[Eidt per comment]
To handle the row[0], row[1] you need a loop like:
for(i=0; i<rows.Count; i++)
{
da.UpdateCommand = new OleDbCommand(String.Format("UPDATE...",row[i]);
da.Update(dt);
}

How to select a subset of rows from a table adapter in the .Net framework

I know that tableadapter does not support the OVER SQL command as in the following SQL statement
SELECT * FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY dbo.alerts.id) NUM,
* FROM dbo.Alerts
) A
WHERE NUM > #StartRow AND NUM < #EndRow
how would you make the equivalent statement so that the dataset designer will support such queries
Basicly I want to be able to select a subset of rows to present to the UI without loading the whole dataset. Maybe I am going about this the wrong way, any guidance would be appreciated
I don't know if this is the direction you want to take, but you could put that sql statement in a stored procedure and use the sproc's parameters to filter the desired subset and then have that get loaded into the dataset.
Doing something like the following:
SqlCommand sqlCommand = new SqlCommand(.........);
sqlCommand.CommandText = "theStoredProcedureNameHere";
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter paramWhatever1 = new SqlParameter(......);
SqlParameter paramWhatever2 = new SqlParameter(......);
sqlCommand.Parameters.Add(paramWhatever1);
sqlCommand.Parameters.Add(paramWhatever2);
SqlDataAdapter sqlAdapter = new SqlDataAdapter();
sqlAdapter.SelectCommand = sqlCommand;
DataSet ds = new DataSet();
sqlAdapter.Fill(ds);
Put your query in a stored procedure instead and call it to fill your dataset

Combobox first values should be null

Using C# & MYSQL
Using Combobox in my webpage, in a combobox i want to display a null values first, then it should display all values..
For Example
Combobox.item = null values
combobox.item = 1
Combobox.item = 2
....,
Code
cmd = new OdbcCommand("Select vehicleno as vehicleno from tb_car", con);
ada = new OdbcDataAdapter(cmd);
ada.Fill(data1);
cmbvnoview.DataValueField = "vehicleno";
cmbvnoview.DataSource = data1;
cmbvnoview.DataBind();
Above code is working, but is displaying all the values, first it should display a null value, then it should display all the values.
How to modify my code....
Need Code Help
Try this after you data bind
...
cmbvnoview.DataBind();
cmbvnoview.Items.Insert(0, new ListItem("Null Values", "-1"));
Change -1 with whatever you feel confortable with. You will have to change your sql to filter out nulls.
OR
try this
cmd = new OdbcCommand("Select IFNULL(vehicleno, 'Null Values')
as vehicleno from tb_car", con);
Your question does not quite make sense so this may not be the right answer.
Just prefix an empty/dummy entry to you datasource.
To keep the logic at one place, just add a null record to your sql statement
cmd = new OdbcCommand("Select null as vehicleno Union Select vehicleno as vehicleno from tb_car", con);

Categories