How can I, using asp.net and HTML, use a form to create a new table row in an SQL Table?
Would I use javascript to retrieve the HTML? Should I directly submit SQL or should I create a stored procedure? Essentially, I want to know how to get the data from a form to my SQL.
Take a look at the example provided in the documentation for the SqlCommand class.
In here they provide a basic example for connecting to a database, executing a query and processing the results. Here is a slightly modified version for doing an insert:
string queryString =
"INSERT INTO MyTable (Column1) Values ('test');";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
command.ExecuteNonQuery();
}
Make sure that you use a Parameterized Query when you use insert values from your web page into your database or you will be vulnerable to SQL Injection attacks.
There are several other methods for doing this such as LINQ-to-SQL, but feel this is the most straight forward for beginners.
Check out this for adding data: http://www.w3schools.com/ado/ado_add.asp
And check out this for updating data: http://www.w3schools.com/ado/ado_update.asp
You should use stored procedures to prevent security risks.
I strongly suggest you read:
ASP.NET Data Access to understand the basics, and then part 2 of step by step mySQL data access using ASP.NET
Related
I am trying to write a paramaterized update query to insert values into an Sql Server Express Database. The query I have written is:
Dim cmd As New SqlCommand
cmd.Connection = conn
cmd.CommandText = "update tblposts set title=#ptitle, pdate=#pd,
content=#pcontent where pid=#p"
cmd.Parameters.AddWithValue("ptitle", txtTitle.Text)
cmd.Parameters.AddWithValue("pcontent", txtcontent.InnerText)
cmd.Parameters.AddWithValue("pd", DateTime.Now.ToString)
cmd.Parameters.AddWithValue("p", postid)
On running cmd.ExecuteNonQuery, I get number of rows affected as 1, but the change is not reflected in the database.
On printing the query using Debug.Write, I get the query not with the parameter values, but the names of the parameters itself (ie. #pcontent, #title etc)
What can be the mistake here?
In you're AddWithValue you need to include the # symbol on the front of the parameter, so:
cmd.Parameters.AddWithValue("#ptitle", txtTitle.Text)
cmd.Parameters.AddWithValue("#pcontent", txtcontent.InnerText)
cmd.Parameters.AddWithValue("#pd", DateTime.Now.ToString)
cmd.Parameters.AddWithValue("#p", postid)
I'm guessing that it's executing correctly but there where clause is blank, so perhaps updating a blank row.
Anyway, try the above and it should update as expected.
Edit to Add
The CommandText will always only have the #value in there, it will not substitue the parameter values into the string.
You would need to loop through the cmd.Parameters collection to write out the values.
I'm converting a web forms application to mvc3 , for the current database it is calling asmx web services returning datasets. Since I'm rebuilding quite a bit of the application I really have no need or desire to be working with datasets. Entity Framework is out of the question for the boss etc... Thus this is the existing type of Oracle code which returns 3 refcursors resulting in the dataset containing 3 datatables. Here is the existing code:
connection = new OracleConnection(EnvironmentSettings.connectionString);
connection.Open();
command = new OracleCommand("H16B.WEB_FACILITY.get_facility_queue", connection);
command.CommandType = CommandType.StoredProcedure;
// Input Parameters
command.Parameters.Add("pfacility", OracleDbType.Varchar2, facilityCode, ParameterDirection.Input);
// Output Parameters
command.Parameters.Add("pqueue", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
command.Parameters.Add("psubmitting", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
command.Parameters.Add("psubmitted", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
adapter = new OracleDataAdapter(command);
DataSet ds = new DataSet();
adapter.Fill(ds);
So What I would like to do is instead of using a dataset, use a collection a List or IEnumerable . Could anyone show me how to capture the data into the list (would I want 3 lists , the current webmethod output is a dataset. Thanks in advance.
If you use Command.ExecuteNonQuery(), each of your ref cursor parameters should contain a Value that is either an OracleDataReader or an OracleRefCursor, depending on the internal settings of the parameter.
So, you should be able to start with something like this:
IDataReader queueReader = (IDataReader)command.Parameters["pqueue"].Value;
If it turns out to be an OracleRefCursor instead, you can use a GetDataReader on it for the same effect.
Since the contents are simple in this case, you may be able to just cast it to an IEnumerable directly; otherwise, you may need to fill a generic list or collection.
Use the DefaulViews from the DataSet Tables, they implement IEnumberable.
About Dataview in the msdn docs:
'Represents a databindable, customized view of a DataTable for sorting, filtering, searching, editing, and navigation.'
UPDATE: If you want to use collections directly as output take a look at this site (horribly formatted though :/)
As you can see in the article, you will have to change something in your Oracle procedures as well. For example if you want to use plsql associative arrays, the output parameters cannot be refcursors, but have to be plsql tables.
OK, this is probably pretty basic stuff, but it took me quite some time to figure it out. And I guess there are a lot more .NET programmers like me, new to Monotouch and SQLite who don't know this.
I use Ado.NET (System.Data) with Monotouch and SQLite. In SQLite, every row of every table has an 64-bit signed integer called ROWID. You can use this, or if you prefer you can specify a field with INTEGER PRIMARY KEY AUTOINCREMENT, which SQLite will link to ROWID.
But how do you retrieve the value of this field after inserting a new record? Something like the ##identity keyword in Sql Server?
Searching around I found that the c-library for iOS of SQLite has a method sqlite3_last_insert_rowid() to retrieve this, but there is no equivalent of that in Mono.Data.Sqlite. In an older implementation (Mono.Data.SqliteClient) there was a LastInsertRowID() method, but that method disappeared in Mono.Data.Sqlite. Why?
SQLite has some internal core functions. One of these functions is last_insert_rowid(). So all you have to do is to issue a command "SELECT last_insert_rowid()". Example in Monotouch:
public long GetLastInsertRowId(SqliteConnection connection)
{
// Assuming connection is an open connection from your INSERT
using (SqliteCommand command = new SqliteCommand("SELECT last_insert_rowid()", connection))
{
return (long)command.ExecuteScalar();
}
}
Or you can combine the select with your insert, example:
string SqlCommand = "INSERT into Customers ([Name], .... [City]) VALUES (#Name, ... #City);SELECT last_insert_rowid();";
I'm using Microsoft .NET Framework 3.5 to create a web service with VB.NET. I'm using a Stored Procedure in SQL Server 2008 so that SQL can insert all the data that I'm passing.
The problem is that in one of the servicse I need to pass around 10,000 records and it's not very efficient to run the stored procedure 10,000 times.
I read that there is a way in which you can pass an XML file with all data to the Stored Procedure but I'm not sure if that's the most efficient way. Also I couldn't make the code work, I don't know if I have to pass the XML as a String.
I'm asking for help with a method in which I can pass a lots of records to the stored procedure once and then the same instance of the Stored procedure can process all the records in a loop
Thank you all in advance.
There is SqlBulkCopy in .NET, but I expect you'll want to look at a table-valued parameter.
You can pass a text batch of statements to the database. It can be quite efficient.
Instead of creating a SqlCommand of CommandType.StoredProcedure and taking a single stored procedure name and set of parameters – which, as you suspect, will perform poorly if you round-trip to the database for each record – you can instead create a SqlCommand of CommandType.Text, and then construct a text batch containing multiple SQL statements (which would be invocations of your stored procedure.) Separate each statement with a semi-colon.
Another advantage of a text batch is that your stored procedure can be kept simple and just process a single record at a time.
But, be careful: You need to ensure your parameters are properly quoted / escaped, because creating a plain text batch instead of using CommandType.StoredProcedure (with parameters) opens you up to SQL-injection type vulnerabilities.
The method I use is to pass the data in a CDATA block (pipe delimited in my case) to the web service, which then:
Saves the CDATA block to a temp file on the web server
Then uses the command line utility bcp.exe to bulk load the data into a staging table
Then calls the stored procedure which is set up to process all the records in the staging table
much faster and less strain on the database than calling the proc for each record.
Edit: Now that I've read about SqlBulkCopy, I would do this instead:
Write the CDATA block data into a DataTable
Use SqlBulkCopy to put the data into a staging table :-)
Then calls the stored procedure which is set up to process all the records in the staging table
http://msdn.microsoft.com/en-us/library/ms186918.aspx
This may also help: http://sqlxml.org/faqs.aspx?faq=61
Where I've done this before with SQL Server 2000, I've used OPENXML (as #EJB suggested) by constructing an XML string in my code, passing it into a stored proc in a text parameter, using OPENXML to parse the XML into a relational structure and going on from there e.g.
VB
Dim xmlStringBuilder As System.Text.StringBuilder
xmlStringBuilder = New System.Text.StringBuilder
xmlStringBuilder.Append("<objects>"
For Each object In Collection
'I'm not suggesting this is the best way to build XML, it is however reliable!
xmlStringBuilder.Append("<object id='" & object.id.ToString & "'></object>"
Next
xmlStringBuilder.Append("</objects>"
Dim xmlStoredProcCommand As SqlCommand
Dim xmlParameter As SqlParameter
xmlStoredProcCommand = New SqlCommand(connection)
xmlStoredProcCommand.CommandType = CommandType.StoredProcedure
xmlStoredProcCommand.CommandText = "xmlStoredProc"
xmlParameter = New SqlParameter("#xmlParameter",SqlDbType.NText)
xmlParameter.Value = xmlStringBuilder.ToString
xmlStoredProcCommand.Parameters.Add(xmlParameter)
xmlStoredProcCommand.ExecuteNonQuery
SQL
CREATE PROCEDURE xmlStoredProc
#xmlParameter NTEXT
AS
BEGIN
DECLARE #xmldochandle INT
DECLARE #objects TABLE (objectID INT)
EXEC sp_xml_preparedocument #xmldochandle OUTPUT, #xmlParameter
INSERT INTO #objects (objectId)
SELECT objectId
FROM OPENXML(#xmldochandle, 'objects/object')
WITH (objectId INT)
EXEC sp_xml_removedocument #xmldochandle
END
and from there you can do your stuff with the contents of the #objects table variable.
I have table on a database on a server, that is identical to a table on my local. I have click once application that needs to download the version of records on the server down to my local.
At the moment i have webservice that pulls back the records on the server in batches, using asp.net datasets as containers. How do i commit the whole dataset to the table in my local? The table on my local is empty.
Cheers in advance!
If you already have a DataSet, containing one or several DataTables, why don't you just use the SqlDataAdapter and call its ".Update()" method with your DataSet?
In the SqlDataAdapter, you can define an InsertCommand, an UpdateCommand, a DeleteCommand which will take care of the three basic insert/update/delete statements for your rows. All you need to do is define / write those three SQL Statements once, and the SqlDataAdapter will do the rest for you (looping through the rows, figuring out whether to insert, update or delete etc.).
If you want, you can even use your basic SELECT statement from the SelectCommand in your DataSet and use the SqlCommandBuilder to build the INSERT, UPDATE and DELETE statements based on your SELECT.
MSDN Library doc on SqlDataAdapter
SQL Data Adapter without SqlCommandBuilder
MSDN Library doc on SqlCommandBuilder
Marc
There are several options. Here are the first two that come to mind.
One would be to loop through the DataTable and build an SQL Insert statement on each loop and then execute the Insert statement against the local.
Another would be to use the SQL Bulk Copy to insert the data