I call
public bool CheckIfFinished ( Guid pid, int sid )
{
// pid: guid corresponding to partner
// sid: survey id
bool finished = false;
using (SqlCommand cmd = new SqlCommand("CheckIfFinished", this._Conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#pid", pid);
cmd.Parameters.AddWithValue("#sid", sid);
this._Conn.Open();
using ( SqlDataReader dataReader = cmd.ExecuteReader() )
{
while (dataReader.Read())
{
finished = dataReader.GetByte(0) == 1 ? true : false;
}
}
this._Conn.Close();
}
return finished;
}
which calls the sproc
GO
-- Create sproc for returning whether a partner has marked their survey as finished
CREATE PROCEDURE CheckIfFinished
#pid UNIQUEIDENTIFIER,
#sid INT
AS
BEGIN
SELECT 1 FROM FinishedMappings WHERE partner_id=#pid AND survey_id=#sid
END
which uses the table FinishedMappings which does exist because it was defined with
CREATE TABLE FinishedMappings (
partner_id UNIQUEIDENTIFIER,
survey_id INT,
PRIMARY KEY (partner_id,survey_id),
FOREIGN KEY (partner_id) REFERENCES Partners(id),
FOREIGN KEY (survey_id) REFERENCES Surveys(id)
);
right above the sproc. Why am I getting the error?
If the table was created using a different user to the one that you are executing the sp with then a fully qualified name could be needed. I would check this first as dimasun suggested in his first reply.
Also check to see if you can execute the sp directly in SQL management studio. If this doesn't work then you can focus on the code in the sp
Related
I am working on ASP.net MVC ...i have made database and now i am using the code below to insert data in the database using View Model class.
But it gives Entity Validation Error on db.savechanges() in user table(as tbl
_user). Please let me know where i am doing mistake.
Code to insert in DB
public string RegisterStudent(RegisterationLoginViewModel svm)
{
tbl_User_Role usr_role = new tbl_User_Role
{
// UserRole_Id=svm.User_Role_id,
RoleName = svm.User_Role,
Dsecription=svm.Description,
OtherDetails=svm.OtherDetails,
};
db.tbl_User_Role.Add(usr_role);
db.SaveChanges();
tbl_User S_Up = new tbl_User
{
FullName = svm.Full_Name,
DOB = svm.Date_of_Birth,
Address = svm.Home_Address,
MobileNumber = svm.Mobile_Number1,
CNIC = svm.CNIC,
Country = svm.Country,
Provience = svm.Provience,
City = svm.City,
UserRole_Id = usr_role.UserRole_Id,
Gender = svm.Gender,
CreatedOn = DateTime.Now,
};
db.tbl_User.Add(S_Up);
db.SaveChanges(); -->**Exception is thrown at this line**
If your UserRole_Id in model tbl_User_Role is not auto generated, then writing this line of code UserRole_Id = usr_role.UserRole_Id giving null because may be it is the Foreign Key of tbl_User table.
Beside, If you have set DatabaseGeneratedOption.Identity then you need to get it's UserRole_Id after saving the usr_role and then assign it to UserRole_Id.
And finally recheck your Required fields are not null and foreign key is getting value.
I'm working on a legacy project and need to insert a row and return either that row or it's identity.
the new row is inserted with the correct values, only nothing is returned in the dataset when it gets back to .net.
I've tried selecting ##identity, RETURN, OUTPUT, but with everything i try the dataset is empty (but not null).
It's not the fault of MyUtils.DBHelper.GetDataSet, as this is used in other places and executes and returns ok.
USE [dbname]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[DuplicateOrder]
(
#sourceid int,
#var1 int,
#var2 decimal(10,2),
)
AS
INSERT INTO OrderHeader (
Users_ID,
Stores_ID,
)
SELECT
#var1,
#var2
FROM Order
WHERE id = #sourceid
GO
The code i'm using to execute the stored procedure is:
Using cmd As New SqlCommand("DuplicateOrder") With {.CommandType = CommandType.StoredProcedure}
cmd.Parameters.AddWithValue("#sourceid", sourceId)
cmd.Parameters.AddWithValue("#var1 ", var1 )
cmd.Parameters.AddWithValue("#var2 ", var2 )
ds = MyUtils.DBHelper.GetDataSet(cmd)
End Using
This should do the trick:
ALTER Procedure [dbo].[DuplicateOrder]
(
#sourceid int,
#var1 int,
#var2 decimal(10,2)
)
AS
INSERT INTO OrderHeader (
Users_ID,
Stores_ID
)
SELECT
#var1,
#var2
SELECT ##IDENTITY AS ident
GO
I tested it on SQL server and it returns one row with the column ident.
have you tried executing this SELECT IDENT_CURRENT ('Table') AS Current_Identity; it should return the last generated identity in the current session and scope
##identity and return wouldn't work (SCOPE_IDENT(), IDENT_CURRENT() as well wouldn't work if you intend to insert multiple rows at once).
Your best bet is to use the OUTPUT but I don't see any OUTPUT in your code. Here is a sample for you (the code part is in C# but you can easily convert it, say using Telerik converter or write yourself - there are N ways to pass the data, I chose XML in this sample):
SQL code to generate sample table and procedure:
USE [Test];
GO
CREATE TABLE IdentityTest
(
Id INT IDENTITY
NOT NULL
PRIMARY KEY ,
FirstName VARCHAR(20) ,
LastName VARCHAR(20)
);
GO
CREATE PROCEDURE InsertTestData
(
#XML VARCHAR(MAX) ,
#NodeName VARCHAR(1000)
)
AS
BEGIN
DECLARE #myIDTable TABLE ( theID INT );
DECLARE #hDoc INT;
DECLARE #tbl TABLE
(
fName VARCHAR(20) ,
lName VARCHAR(20)
);
EXEC sp_xml_preparedocument #hDoc OUTPUT, #XML;
INSERT #tbl
SELECT *
FROM OPENXML(#hDoc, #NodeName, 1) WITH (fName VARCHAR(20), lName VARCHAR(20));
EXEC sp_xml_removedocument #hDoc;
INSERT INTO [IdentityTest] ( [FirstName], [LastName] )
OUTPUT [Inserted].[Id]
INTO #myIDTable
SELECT t.[fName], t.[lName]
FROM #tbl AS t;
SELECT *
FROM #myIDTable AS [mit];
END;
GO
And this is the C# code using the SP and inserting multiple rows and getting back their IDs (might have returned the full row data):
void Main()
{
List<Person> people = new List<Person> {
new Person { FName = "Sam", LName="Jones"},
new Person { FName = "Cetin", LName="Basoz"},
new Person { FName = "John", LName="Doe"},
new Person { FName = "Steven", LName="Smith"},
new Person { FName = "Bob", LName="Carpenter"},
};
for (int i = 0; i < 100; i++)
{
people.Add(new Person
{
FName = string.Format("FName#{0}", i),
LName = string.Format("LName#{0}", i)
});
}
var peopleAsXML = new XElement("People",
from p in people
select new XElement("Person",
new XAttribute("fName", p.FName),
new XAttribute("lName", p.LName)));
string sql = #"InsertTestData";
DataTable result = new DataTable();
using (SqlConnection con = new SqlConnection(#"server=.\SQLExpress2012;Trusted_Connection=yes;Database=Test"))
{
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#XML", peopleAsXML.ToString());
cmd.Parameters.AddWithValue("#NodeName", "/People/Person");
con.Open();
result.Load(cmd.ExecuteReader());
con.Close();
}
// check top 5 returned
for (int i = 0; i < 5; i++)
{
Console.WriteLine((int)result.Rows[i]["theID"]);
}
}
public class Person
{
public string FName { get; set; }
public string LName { get; set; }
}
I need help from All Dapper master.
I have been learning using Dapper since one month ago, but I have error when executing query using ODBC SP.
The code originally was written by someone(DapperExample) but not using ODBC, thanks to the writer I forgot your name.
My SP:
CREATE PROCEDURE SP_GET_FIND_EMPLOYEES (#EmpID INT)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM tblEmployee WHERE EmpID = #EmpID
END
GO
My Code
public class EmployeeDashBoard : IEmployeeDashBoard
{
private IDbConnection _db;
string connStr2 = WebConfigurationManager.ConnectionStrings["DapperExample"].ConnectionString;
public EmployeeDashBoard()
{
}
public Employee Find(int id)
{
//type b, by sp
using (IDbConnection connection = new OdbcConnection(connStr2))
{
var p = new DynamicParameters();
p.Add("#EmpID", id);
Employee result = this._db.Query<Employee>("dbo.SP_GET_FIND_EMPLOYEES", new { #EmpID = id }, commandType: CommandType.StoredProcedure).Single();
return result;
}
}
}
Error:
ERROR [42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Procedure or function 'SP_GET_FIND_EMPLOYEES' expects parameter '#EmpID', which was not supplied.
Thanks in Advance.
Masa Sih
I Solved by my self, I'm using Sybase ODBC SP, ( God Job Sam ), now I can avoid entity framework in the feature.
Here the tricks:
Solved: SP_GET_FIND_EMPLOYEES ?
using (IDbConnection connection = new OdbcConnection(connStr2))
{
var p = new DynamicParameters();
p.Add("?EmpID?", id.ToString());
Employee result = this._db.Query<Employee>("dbo.SP_GET_FIND_EMPLOYEES ?", p, commandType: CommandType.StoredProcedure).Single();
return result;
}
Your implementation for ODBC named parameters is incorrect. You encase the named parameter with question marks in your statement and create the named parameter without the question marks. The question marks are used by Dapper to parse the statement to find the names.
p.Add("EmpID", id.ToString());
Employee result = this._db.Query<Employee>("dbo.SP_GET_FIND_EMPLOYEES ?EmpID?", p, commandType: CommandType.StoredProcedure).Single();
See this answer for more information: https://stackoverflow.com/a/26484944/6490042
My code is
public Emp GetEmpByEmpno(int empno)
{
using (con)
{
if (con.State == ConnectionState.Closed)
{
con.ConnectionString = constr;
con.Open();
}
cmd.CommandText = "sp_emp_GetempByEmpno";
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#eno",empno);
dr=cmd.ExecuteReader();
Emp obj=null;
while(dr.Read())
{
obj=new Emp();
obj.Empno=int.Parse(dr["Empno"].ToString());
obj.Ename=dr["Ename"].ToString();
obj.Sal=dr["Sal"].ToString();
obj.Deptno=int.Parse(dr["Deptno"].ToString());
}
return obj;
}
}
Here I fetch the record based on employee number, whenever i pass empno in textbox search button onClick, the respective employee should display in grid view. How can i bind the object to grid view?
Employee obj=EmpDeptBus.GetEmployeeByEmpno(int.Parse(txtEmpno.Text));
gvemp.DataSource = c;
gvemp.DataBind();
You should be able to just say
gvemp.DataSource = obj;
That's really all you need to do to bind the object.
Also, change your
while(dr.Read())
to
if(dr.Read())
You're only expecting one record so only fetch one. Also put your return obj outside your using to make sure everything is properly disposed before you return to the calling function.
Try making sure that txtEmpno.Text holds an int value before you attempt to pass it to this method or it will blow up. Never, ever trust user input. You could do something like:
int empNo = 0;
if(int.TryParse(txtEmpNo.Text.Trim(), out empNo)
{
// then call the function and bind your grid using the empNo as the
// variable holding the employee number.
}
else
{
// otherwise handle the fact that the user entered a non-numeric.
}
I am checking out v1.25 of Dapper with Sqlite via System.Data.Sqlite. If I run this query:
var rowCount = dbc.Query<int>("SELECT COUNT(*) AS RowCount FROM Data").Single();
I get the following error: System.InvalidCastException: Specified cast is not valid
This is because Sqlite returns the above value as an Int64, which I can verify with the following code. This will throw "Int64":
var row = dbc.Query("SELECT COUNT(*) AS RowCount FROM Data").Single();
Type t = row.RowCount.GetType();
throw new System.Exception(t.FullName);
Now, the following code will actually handle the downward conversion from Int64 to Int32:
public class QuerySummary
{
public int RecordCount { get; set; }
}
var qs = dbc.Query<QuerySummary>("SELECT COUNT(*) AS RecordCount FROM Data").Single();
rowCount = qs.RecordCount;
throw new System.Exception(rowCount.ToString());
When I throw this exception, it gives me the actual row count, indicating that Dapper handled the conversion for me.
My question is, why is it that dbc.Query<int> does not handle the downward conversion in a similar way to dbc.Query<QuerySummary>? Is this intended behavior?
No, that is not intentional. I've committed and pushed changes to github which make the following pass (it fails on 1.25); it should appear on NuGet at some point soon too:
// http://stackoverflow.com/q/23696254/23354
public void DownwardIntegerConversion()
{
const string sql = "select cast(42 as bigint) as Value";
int i = connection.Query<HasInt32>(sql).Single().Value;
Assert.IsEqualTo(42, i);
i = connection.Query<int>(sql).Single();
Assert.IsEqualTo(42, i);
}