User Defined Stored Procedure which returns multiple actual table as result set.
CREATE PROCEDURE uspDemo(
#UserID BIGINT=0,
#IsAdmin bit=0,
#Title varchar(120)=''
)AS
BEGIN
------Retrieve Posts------
SELECT * FROM tblPost AS MP INNER JOIN tblUserProfile AS UP ON UP.ID=MP.UserID
WHERE UP.ID=#UserID AND ((#IsAdmin=0 AND MP.IsDeleted=0 AND MP.IsApproved=1)OR (#IsAdmin=1 OR MP.IsDeleted=0 OR MP.IsApproved=1))
----- Retrieve Tags------
SELECT * FROM tblTagMasters AS MT INNER JOIN tblPostTags AS MP ON MT.TagID= MP.TagID
--------Retrieve User likes-----
SELECT * FROM tblUserLikes AS UV INNER JOIN tblPost AS MP ON MP.PostId=UV.PostId
END
I want to convert into list format of all returned actual table from stored procedure according to model in asp.net MVC.
public List<PostView> GetPosts(int userID = 0, string s = "")
{
IEnumerable<PostView> query = null;
using (var db = new MVCDatabase())
{
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[uspDemo]";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#UserID", userID));
cmd.Parameters.Add(new SqlParameter("#IsAdmin", 0));
cmd.Parameters.Add(new SqlParameter("#Title", s));
try
{
db.Database.Connection.Open();
using (var result = cmd.ExecuteReader())
{
var Posts = ((IObjectContextAdapter)db).ObjectContext.Translate<PostView>(result).ToList();
result.NextResult();
var tags = ((IObjectContextAdapter)db).ObjectContext.Translate<TagView>(result).ToList();
result.NextResult();
var uservotes = ((IObjectContextAdapter)db).ObjectContext.Translate<UserVoteView>(result).ToList();
Posts.ForEach(z =>
{
z.TagMaster = tags.Where(x => x.PostId == z.PostId).ToList();
z.UserLike = uservotes.Where(x => x.PostId == z.PostId).ToList();
});
query = Posts;
}
}
catch (Exception ex)
{
MSError.Trace(ex);
}
finally
{
db.Database.Connection.Close();
cmd.Dispose();
}
return query.ToList();
}
}
Throwing an ArgumentNullException
Help me to find out the solution.
Here is a demo how to do it. Using System.data and System.Linq you can do below.
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[uspDemo]";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#UserID", userID));
cmd.Parameters.Add(new SqlParameter("#IsAdmin", 0));
cmd.Parameters.Add(new SqlParameter("#Title", s));
SqlDataAdapter da = new SqlDataAdapter(); //adapter
DataSet ds = new DataSet(); //dataset
cmd.CommandType = CommandType.StoredProcedure;
da = new SqlDataAdapter(cmd);
da.Fill(ds); //fill dataset with multiple select
var Posts = (from DataRow row in ds.Tables[0].Rows //0 means 1st select
select new Posts //Posts model to map
{
test = row["test"].ToString(), //test is the column name from select
test1 = Convert.ToDecimal(row["test1"])
}).ToList();
var Tags = (from DataRow row in ds.Tables[1].Rows //1 means 2nd select
select new Tags //Tags model to map
{
test = row["test"].ToString(), //test is the column name from select
test1 = Convert.ToDecimal(row["test1"])
}).ToList();
var User = (from DataRow row in ds.Tables[2].Rows //2 means 3rd select
select new User //User model to map
{
test = row["test"].ToString(), //test is the column name from select
test1 = Convert.ToDecimal(row["test1"])
}).ToList();
I am trying to save one Gridview with two checkbox in database with Asp.net Transaction , I am Getting Error when same condition come
SqlCommand cmd = new SqlCommand("procedure", con);
SqlCommand cmd1 = new SqlCommand("procedure1", con);
foreach (GridViewRow row in gvrecept.Rows)
{
if (cash.Checked){
cmd.Parameters.AddWithValue("#parameter", "value");
cmd.Transaction = trns;
}
else if (cheque.Checked)
{
cmd1.Parameters.AddWithValue("#parameter1", "value1");
cmd1.Transaction = trns;
}
}
int i = cmd1.ExecuteNonQuery();
int j = cmd.ExecuteNonQuery();
if (i > 0 && j > 0 )
{
trns.Commit();
}
As explained in my comment above you need to change something:
The trns should be added outside the loop just one time together with the setting to CommandType = CommandType.StoredProcedure and the creation of the two commands.
Inside the loop you should execute the command at each loop for each row you traverse. Also it is not clear if the two commands are mutually exclusive. I mean, if you have two checkboxes set then you should execute both commands but not if you don't have the matching checkbox set. If this is the case you need to use two separate ifs not an else if.
Notice that inside the loop you can simply change the value of the parameter before executing the command. This will be a smaller optimization but nevertheless it is simpler than creating the command or clearing the parameter collection at each loop.
Finally the commit of the Transaction should be done outside the loop when you have completed the insertion. If you have an error then an exception occurs and the Commit is skipped.
Final note. It is not clear why you need two commands at all. In the code above you use always the same StoredProcedure but passing different values. If this is the case then one command will do just fine.
SqlCommand cmd = new SqlCommand("procedure1", con);
cmd.Transaction = trns;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#parameter", SqlDbType.NVarChar);
SqlCommand cmd1 = new SqlCommand("procedure1", con);
cmd1.Transaction = trns;
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.Add("#parameter1", SqlDbType.NVarChar);
foreach (GridViewRow row in gvrecept.Rows)
{
if (cash.Checked)
{
cmd.Parameters["#parameter"].Value = "value";
cmd.ExecuteNonQuery();
}
if (cheque.Checked)
{
cmd.Parameters["#parameter1"].Value = "value1";
cmd1.ExecuteNonQuery();
}
}
trns.Commit();
I have the following classic asp working, calling a stored proc in the database. I would like to convert it over so instead of calling the stored proc it passes in the sql, adds the prams then executes it.
I tried all sorts of things and can't get it working.
Can someone convert this example?
Also it seems difficult to get reasonable error messages when passing in sql with params. Is there a way to see traces of this call so we can have some idea what is causing the problem?
Set cmd = server.createobject("ADODB.Command")
cmd.ActiveConnection = theDatabase
cmd.CommandType = adCmdStoredProc
cmd.commandText = "AddResponse"
cmd.Parameters("#id") = id
cmd.Parameters("#pc") = pc
cmd.Parameters("#idDate") = now
cmd.Execute , , adExecuteNoRecords
set cmd = Nothing
Stored Procedure definition
ALTER PROCEDURE [dbo].[AddResponse] #id NVARCHAR(12), #pc NVARCHAR(12), #idDate datetime
AS
BEGIN
SET NOCOUNT ON;
select * from EmailResponse
if not exists (SELECT id, projectCode FROM EmailResponse WHERE id = #id and projectCode = #pc)
begin
INSERT INTO EmailResponse (id, projectCode, dateEntered) VALUEs(#id, #pc, #idDate)
end
END
EDIT:
Here are my answers to everyone.
Wow stackoverflow is great because of everyone like yourselves
who spend a little time helping others.
the select * was a mistake
I have to maintain and convert some older asp code over to using stored procs.
Stored proc are the way to go "most" of the time.
For various reasons sometimes it is better to have the sql in the code.
(quick testing and development, no access to the database, etc.)
So I need to know how to handle both ways.
cmd.Parameters.Refresh
My code works fine without this call.
It is really necessary?
Reading what it is supposed to do was not a lot of help why I need to use it
Understanding types is critical for all types of programming.
This was exactly what I was asking for and more.
Carl Prothman - Data Type Mapping
Thanks for this!
I was also wondering how to set a record set object even though I forgot to ask. Thanks for this too!
set rs = server.createObject ("adodb.recordset")
rs =- cmd.Execute
I got all three working.
For anyone interested here is working and tested code to show all three approaches.
' Stored proc example
' ------------------------------------------
dim theDatabase, cmd, id, pc
theDatabase = "Driver={SQL Server}; Server=10.10.10.10,1433; Database=Test; uid=TestUser; pwd=TestPass;"
id = cleanInt(request.querystring("id"))
pc = sqlSafe(clean(request.querystring("pc")))
if pc<>"" and id<>"" then
Set cmd = server.createobject("ADODB.Command")
cmd.ActiveConnection = theDatabase
cmd.CommandType = adCmdStoredProc
cmd.commandText = "AddResponse"
cmd.Parameters("#id") = id
cmd.Parameters("#pc") = pc
cmd.Parameters("#idDate") = now
cmd.Execute , , adExecuteNoRecords
set cmd = Nothing
end if
' Inline SQl with ? example
' ------------------------------------------
dim theDatabase, cmd, id, pc
theDatabase = "Driver={SQL Server}; Server=10.10.10.10,1433; Database=Test; uid=TestUser; pwd=TestPass;"
id = cleanInt(request.querystring("id"))
pc = sqlSafe(clean(request.querystring("pc")))
if pc<>"" and id<>"" then
Set cmd = server.createobject("ADODB.Command")
cmd.ActiveConnection = theDatabase
cmd.CommandType = adCmdText
cmd.CommandText = _
"if not exists (SELECT id, projectCode FROM EmailResponse WHERE id = ? and projectCode = ?)" &_
"begin INSERT INTO EmailResponse (id, projectCode, dateEntered) VALUEs(?, ?, ?) end "
cmd.Parameters.Append cmd.CreateParameter("#id", adInteger, adParamInput, , id)
cmd.Parameters.Append cmd.CreateParameter("#pc", adVarchar, adParamInput, 12, pc)
cmd.Parameters.Append cmd.CreateParameter("#id2", adInteger, adParamInput, , id)
cmd.Parameters.Append cmd.CreateParameter("#pc2", adVarchar, adParamInput, 12, pc)
cmd.Parameters.Append cmd.CreateParameter("#idDate", adDBTimeStamp, adParamInput, -1, now)
cmd.Execute , , adExecuteNoRecords
set cmd = Nothing
end if
' Inline SQl with # example
' ------------------------------------------
dim theDatabase, cmd, sql, id, pc
theDatabase = "Driver={SQL Server}; Server=10.10.10.10,1433; Database=Test; uid=TestUser; pwd=TestPass;"
id = cleanInt(request.querystring("id"))
pc = sqlSafe(clean(request.querystring("pc")))
if pc<>"" and id<>"" then
Set cmd = server.createobject("ADODB.Command")
sql = ""
sql = sql & "SET NOCOUNT ON;" & vbCrLf
sql = sql & "DECLARE #id NVARCHAR(12)" & vbCrLf
sql = sql & "DECLARE #pc NVARCHAR(12)" & vbCrLf
sql = sql & "DECLARE #idDate DATETIME" & vbCrLf
sql = sql & "SELECT #id = ?, #pc = ?, #idDate = ?" & vbCrLf
sql = sql & "IF NOT EXISTS (SELECT id, projectCode FROM EmailResponse WHERE id = #id and projectCode = #pc)" & vbCrLf
sql = sql & "INSERT INTO EmailResponse (id, projectCode, dateEntered) VALUEs(#id, #pc, #idDate);"
cmd.ActiveConnection = theDatabase
cmd.CommandType = adCmdText
cmd.CommandText = sql
cmd.Prepared = true
cmd.Parameters.Append cmd.CreateParameter("#id", adInteger, adParamInput, , id)
cmd.Parameters.Append cmd.CreateParameter("#pc", adVarchar, adParamInput, 12, pc)
cmd.Parameters.Append cmd.CreateParameter("#idDate", adDBTimeStamp, adParamInput, -1, now)
cmd.Execute , , adExecuteNoRecords
set cmd = Nothing
end if
Thanks everyone.
There is nothing wrong with the above code you are just missing using the Refresh() method of the Parameters collection before trying to set the named parameter values.
Set cmd = server.createobject("ADODB.Command")
With
.ActiveConnection = theDatabase
.CommandType = adCmdStoredProc
.commandText = "AddResponse"
'Query the provider for the parameter details
Call .Parameters.Refresh()
.Parameters("#id") = id
.Parameters("#pc") = pc
.Parameters("#idDate") = now
Call .Execute(, , adExecuteNoRecords)
End With
set cmd = Nothing
If you don't want to use this method the parameter definitions have to come from somewhere so the other option is to define them yourself to reflect the definitions of the stored procedure.
Set cmd = server.createobject("ADODB.Command")
With cmd
.ActiveConnection = theDatabase
.CommandType = adCmdStoredProc
.commandText = "AddResponse"
'Define parameters manually
Call .Parameters.Append(.CreateParameter("#id", adVarWChar, adParamInput, 12))
Call .Parameters.Append(.CreateParameter("#pc", adVarWChar, adParamInput, 12))
Call .Parameters.Append(.CreateParameter("#idDate", adDBTimeStamp, adParamInput, 8))
.Parameters("#id") = id
.Parameters("#pc") = pc
.Parameters("#idDate") = now
Call .Execute(, , adExecuteNoRecords)
End With
set cmd = Nothing
If you do go down the manual route a great resource for identifying what ADO DataTypeEnum constants to use is Carl Prothman - Data Type Mapping
Side-note: You have this line in your Stored Procedure;
select * from EmailResponse
Which expects to return a resultset but you specify adExecuteNoRecords in your ADODB.Command Execute() method which causes this to be ignored, if you do want to return it adjust the above to be;
Dim rs
...
With cmd
...
Set rs = .Execute()
End With
... is used to show where code is omitted
Needs pointing out that while #dimason approach (since removed, not sure why...) is sound it does over complicate things by adding two extra parameters when they are not needed, you can just declare the parameters inside the dynamic SQL and assign them to use those locally declared variables to run the statements instead.
Dim sql
sql = ""
sql = sql & "SET NOCOUNT ON;" & vbCrLf
sql = sql & "DECLARE #id NVARCHAR(12)" & vbCrLf
sql = sql & "DECLARE #pc NVARCHAR(12)" & vbCrLf
sql = sql & "DECLARE #idDate DATETIME" & vbCrLf
sql = sql & "SELECT #id = ?, #pc = ?, #idDate = ?" & vbCrLf
sql = sql & "SELECT * FROM EmailResponse;" & vbCrLf
sql = sql & "IF NOT EXISTS (SELECT id, projectCode FROM EmailResponse WHERE id = #id and projectCode = #pc)" & vbCrLf
sql = sql & "INSERT INTO EmailResponse (id, projectCode, dateEntered) VALUEs(#id, #pc, #idDate);"
Set cmd = server.createobject("ADODB.Command")
With cmd
.ActiveConnection = theDatabase
.CommandType = adCmdText
.CommandText = sql
.Prepared = true
.Parameters.Append cmd.CreateParameter("#id", adVarChar, adParamInput, 12, id)
.Parameters.Append cmd.CreateParameter("#pc", adVarChar, adParamInput, 12, pc)
.Parameters.Append cmd.CreateParameter("#idDate", adDBTimeStamp, adParamInput, 8, Now())
Set rsOut = .Execute()
End With
Set cmd = Nothing
Useful Links
Answer to ADODB.Parameters error '800a0e7c' Parameter object is improperly defined. Inconsistent or incomplete information was provided - Some information about manually defining a Parameter to avoid errors.
To switch from a stored procedure to inline SQL, you need to change
cmd.CommandType = adCmdStoredProc
to
cmd.CommandType = adCmdText
Then you need to add the query to the command text property:
cmd.CommandText = "SELECT * FROM Orders WHERE CustomerID = ?"
The above line was derived from the Command Object Parameters example on MSDN.
// e,g, I want to insert 3 columns in 1st row and 10 columns in rest of the rows
//I am Creating excel file with sheet name as MySheet
// then updating value in 1st row, 1st cell of header as blank
//then inserting data
// Can anyone please help to insert data in excel without header
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName +
";Mode=ReadWrite;Extended Properties=\"Excel 12.0 XML;HDR=NO\"";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = conn;
cmd.CommandText = "CREATE TABLE [MySheet] (a string)";
cmd.ExecuteNonQuery();
cmd.CommandText = "UPDATE [MySheet$] SET F1 = \"\"";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [MySheet] (a) values ('ABC')" //<-----Getting error to insert
cmd.ExecuteNonQuery();
}
}
conn.Close();
Just try [removed the (a)]
cmd.CommandText = "INSERT INTO [MySheet] values ('ABC')";
I get the same error. There was a padded space ending column name in Excel. Removing that space from end of column name fixed the issue.
I am using Visual Foxpro 8.0 database. Below procedure I am using to return records from database on basis of condition matching but it raised error that:
"Function is not implemented."
Foxpro Procedure ------------------------
PROCEDURE FX_Proc_ValidateUser (paramUserName AS Character, paramPassword AS Character)
LOCAL VarUserName AS Character, varXml
VarUserName = IIF(VARTYPE(paramUserName)!="N","",paramUserName)
LOCAL VarPassword AS Character
VarPassword = IIF(VARTYPE(paramPassword)!="N","",paramPassword)
SELECT userinfoid, ;
username, ;
password ;
FROM tm_userinfo.dbf ;
WHERE username = VarUserName AND password = VarPassword ;
INTO CURSOR procResult
varXml = ""
CURSORTOXML("procResult","varXml",1,32,0,"1")
RETURN varXml
ENDPROC
Front End code for calling this procedure------------------
string ConnectionString = "Provider=VFPOLEDB.1;Data Source=C:\Users\raj\Documents\Visual FoxPro Projects\dbFoxMaster.dbc;Collating Sequence=machine;" providerName="System.Data.OleDb.OleDbConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
OledbConnection objOleDbConnection = new OleDbConnection(ConnectionString);
objOleDbConnection.Open();
OleDbCommand objOleDbCommand = new OleDbCommand();
objOleDbCommand.CommandType = CommandType.StoredProcedure;
objOleDbCommand.CommandText = "FX_Proc_ValidateUser";
objOleDbCommand.Connection = objOleDbConnection;
objOleDbCommand.Parameters.Add("paramUserName", OleDbType.Char).Value = "abc";
objOleDbCommand.Parameters.Add("paramPassword", OleDbType.Char).Value = "123";
var xmlString = oOleDbCommand.ExecuteScalar().ToString();
DataTable table = new DataTable();
using (var reader = new StringReader(xmlString))
{
var dataSet = new DataSet();
// creating a dataset from the xml
dataSet.ReadXml(reader);
table = dataSet.Tables[0];
}
How to get resultset from foxpro 8.0 stored procedure using OledbCommand?
It looks like the problem is that you are putting your results into an array and only the first item in the array is being returned. You should change the stored procedure so that it uses a cursor.
VFP9 Example
Here is a stored procedure example from the northwind.dbc:
Here is an example of calling the stored procedure using C#:
var northwindDbcPath = #"C:\Program Files (x86)\Microsoft Visual FoxPro 9\Samples\Northwind\Northwind.dbc";
var connectionString = "Provider=VFPOLEDB.1;Data Source=" + northwindDbcPath;
var table = new DataTable();
using(var connection = new OleDbConnection(connectionString)) {
using(var command = connection.CreateCommand()) {
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "CustOrdersDetail";
command.Parameters.Add("x", 10248);
var adapter = new OleDbDataAdapter(command);
adapter.Fill(table);
}
}
VFP8 Example:
(I don't have a copy of VFP8 but I believe that this will work)
var northwindDbcPath = #"C:\Program Files (x86)\Microsoft Visual FoxPro 9\Samples\Northwind\Northwind.dbc";
var connectionString = "Provider=VFPOLEDB.1;Data Source=" + northwindDbcPath;
DataTable table;
using(var connection = new OleDbConnection(connectionString)) {
using(var command = connection.CreateCommand()) {
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "CustOrdersDetail2";
command.Parameters.AddWithValue("x", 10248);
connection.Open();
// executing stored procedure and getting xml result
var xml = command.ExecuteScalar() as string;
connection.Close();
using(var reader = new StringReader(xml)) {
var dataSet = new DataSet();
// creating a dataset from the xml
dataSet.ReadXml(reader);
table = dataSet.Tables[0];
}
}
}
I have no VFP around and the last time I used VFP it was still version 3.0...
I would try something like this based on the specs here. To learn the rest read-up here
PROCEDURE insertData (pusername, ppassword)
SELECT userinfoid, username, password
FROM tm_userinfo.dbf
WHERE username = pusername AND password = ppassword
INTO ARRAY results
RETURN results
ENDPROC
A Visual Foxpro stored procedure is basically using Visual Foxpro code to perform tasks such as validating columns on insert or update or delete.
For Example, you might add the following code to VFP database stored procedure to validate a "State" column:
PROCEDURE ValidateState()
IF address.state <> [OH]
MESSAGEBOX([Incorrect State value!], 48, [Invalid State])
ENDIF
ENDPROC
For querying a table in a Foxpro database, you may want to look at creating local views. You can do this by right clicking inside the foxpro database and selecting "New Local View", then define your view using the query builder. In the Filter tab, under the "Example" column, you can define parameters using the "?" such as "?pusername".
Here is how you would call the view from your Foxpro code:
LOCAL pusername AS Integer
pusername = "SomeUserName" &&Use this to filter the view
SELECT 0
USE MyViewName &&This will call the view and perform the filter.
You can also make these views updatable and perform your inserts against the view.