Bulk insert with EF ExecuteStoreCommand not working, what is wrong? - entity-framework

I am using SQL 2008 and EF
I have following stored proc for bulk insert
CREATE Type [dbo].[xxx] as Table (
[ErrorCode] [nvarchar](10),
[ErrorMessage] [nvarchar](300),
[FieldName] [nvarchar](50),
[FieldLable] [nvarchar](300),
)
CREATE procedure dbo.InsertAll(#Records xxx READONLY)
as
begin
insert into dbo.MyTable
select * from #Records;
end;
go
I am passing a Datatable as parameter (Type=structured) that has multiple records
This proc works when called using SQLCommand.ExecuteNonQuery, but does not do anything when called using contextObject.ExecuteStoreCommand. The return value = affected rows is always 0
Whats wrong? are such procedures not supported with EF? I am not even getting any exception :(
Update: After running SQL trace just realized the difference in the SQL statements being generated
When using contextObject.ExecuteStoreCommand
declare #p3 dbo.xxx
insert into #p3 values(N'M',N'ErrorMsg - 0',NULL,NULL)
insert into #p3 values(N'M',N'ErrorMsg - 1',NULL,NULL)
insert into #p3 values(N'M',N'ErrorMsg - 2',NULL,NULL)
exec sp_executesql N'InsertAll',N'#Records [xxx]
READONLY',#Records=#p3
When using SQLCommand.ExecuteNonQuery
declare #p1 dbo.xxx
insert into #p1 values(N'M',N'ErrorMsg - 0',NULL,NULL)
insert into #p1 values(N'M',N'ErrorMsg - 1',NULL,NULL)
insert into #p1 values(N'M',N'ErrorMsg - 2',NULL,NULL)
exec InsertAll #Records=#p1
How can I get contextObject.ExecuteStoreCommand to execute the same SQL stmt like SQLCommand.ExecuteNonQuery?

I have found it necessary to provide extension methods when the Entity Framework simply will not work for what I want it to do. The good part is adding an extension to the Context object will usually keep you from having to dig into the web.config or app.config for a connection string. Then parameters and return values can be generic. I have personally seen quite a few eloquent solutions using this strategy.

Related

Postgres SQL - Output Clause into a scalar variable

For the below code which is in SQL server needs to be converted into PostgresSQL. I did try the same way we do in SQL Server but it dint work.
declare #ID table (ID int)
insert into MyTable(ID)
output inserted.ID into #ID
values (1)
So the above code works well in SQL server but when it comes to Postgres it does not work.
Can someone help in converting this code to Postgres ? Also can someone help me in getting a sample SP with inout and out parms in Postgres please.
Assuming this is part of a stored function (or procedure) written in PL/pgSQL, you can use the returning clause as documented in the manual:
....
declare
l_generated_id int;
begin
...
insert into my_table(id)
values (1)
returning id into l_generated_id;
...
end;
But I have to admit that this seems rather unnecessary as the inserted value is hardcoded in the INSERT statement

Entity Framework, execute a Stored Procedure and Variable WHERE Clause

I am trying to execute a stored procedure with EF and a variable WHERE clause.
What I first thought was this :
ALTER PROCEDURE SP
#WHEREClause VARCHAR(250)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL Varchar(8000)
SET #SQL ='Select ...' + #WHEREClause
EXEC(#SQL)
END
Problem here EF wont recognize the selected values from the stored procedure anymore.
So I think of something like that:
ALTER PROCEDURE SP
#WHEREClause VARCHAR(250)
AS
BEGIN
SET NOCOUNT ON;
Select ... FROM ... #WHEREClause
END
Anyone got an idea?
Thanks
Markus
First of all, creating a WHERE clause like this could leave you vulnerable to SQL injection. You might be able to do it safer by using LINQ to narrow down the data rather than a dynamically built WHERE.
Another way to handle it is to use the ExecuteStoreQuery method (this is Database.SqlQuery in EF5). This will allow you to load the results of the stored procedure into a POCO object. You can also parametrize the query which might make it safer, depending on how it's constructed.

TVP - are they used for input and output?

I've started to read the notes on Table Value Parameters
HERE ON MSDN
HERE ON SOMMARSKOG
Can these TVPs be used as input parameters and output parameters?
Is there a point in having them as an output parameter?
I get the feeling it might be possible to have a TVP as output from one stored procedure and then that feeding into another stored procedure - possible?
The syntax of the script which calls the first sproc and then calls the second sproc using the output TVP from the first is the bit I'm unsure of.
EDIT
Apologies for the confusion of my post - it seems that the initial procedures results need to go into the TVP - I thought that the TVP needed to be involved within that sproc. So a model of what I was talking about is the following - hopefully a valid use of TVPs...
CREATE TYPE myfirstTVP AS TABLE (id INT NOT NULL PRIMARY KEY);
GO --<<this sproc will find the ids (+ other fields) that need to be investigated
CREATE PROC test1 as
SELECT 1 UNION
SELECT 2 UNION
SELECT 3;
GO
GO --<<this sproc uses the found ids to do one aspect of the investigation
CREATE PROC test2
#t2 myfirstTVP READONLY
AS
SELECT id*2
FROM #t2;
GO
GO --<<this sproc uses the found ids to do another aspect of the investigation
CREATE PROC test3
#t4 myfirstTVP READONLY
AS
SELECT id*3
FROM #t4;
GO
--<<this is where the TVP is used and the sprocs are called
DECLARE #t3 myfirstTVP ;
INSERT INTO #t3
EXEC test1;
EXEC test2 #t3;
EXEC test3 #t3;
I'm not 100% sure what you want to achieve, but you can in a sense emulate behaviour of 'output' parameters ,
CREATE TYPE LIST_OF_INT AS TABLE (id int not null primary key);
GO
create procedure test1 as
begin
declare #t1 LIST_OF_INT;
insert into #t1 (id) values (1);
select * from #t1;
end;
GO
declare #t2 LIST_OF_INT ;
insert into #t2
EXEC test1;
select * from #t2;
I think you missed this bit from the MSDN link you cited.
Table-valued parameters must be passed as input READONLY parameters to
Transact-SQL routines.

How can I call sp_executesql stored procedure in entity framework?

How can I call sp_executesql stored procedure in entity framework?
I need to dynamically execute formulas stored in SQL Server table column using Select Statement. I tried ENTITY SQL but it does not work.
Use ObjectContext.ExecuteStoreCommand (requires EF 4).
if i understood correctly try this
CREATE PROCEDURE sp_calculatesalary(#EmployeeId as int)
begin
declare #dynsql varchar(500)=' Salary,Username from employee where EmployeeId=#empID'
exec sp_executesql #dynsql,'#empID int',#empID=#EmployeeID
SELECT 1 as salary,2 as username
end
it solves stored procedures mapping problem

Navigating the results of a stored procedure via a cursor using T-SQL

Due to a legacy report generation system, I need to use a cursor to traverse the result set from a stored procedure. The system generates report output by PRINTing data from each row in the result set. Refactoring the report system is way beyond scope for this problem.
As far as I can tell, the DECLARE CURSOR syntax requires that its source be a SELECT clause. However, the query I need to use lives in a 1000+ line stored procedure that generates and executes dynamic sql.
Does anyone know of a way to get the result set from a stored procedure into a cursor?
I tried the obvious:
Declare Cursor c_Data For my_stored_proc #p1='foo', #p2='bar'
As a last resort, I can modify the stored procedure to return the dynamic sql it generates instead of executing it and I can then embed this returned sql into another string and, finally, execute that. Something like:
Exec my_stored_proc #p1='foo', #p2='bar', #query='' OUTPUT
Set #sql = '
Declare Cursor c_Data For ' + #query + '
Open c_Data
-- etc. - cursor processing loop etc. goes here '
Exec #sql
Any thoughts? Does anyone know of any other way to traverse the result set from a stored proc via a cursor?
Thanks.
You could drop the results from the stored proc into a temp table and select from that for your cursor.
CREATE TABLE #myResults
(
Col1 INT,
Col2 INT
)
INSERT INTO #myResults(Col1,Col2)
EXEC my_Sp
DECLARE sample_cursor CURSOR
FOR
SELECT
Col1,
Col2
FROM
#myResults
Another option may be to convert your stored procedure into a table valued function.
DECLARE sample_cursor CURSOR
FOR
SELECT
Col1,
Col2
FROM
dbo.NewFunction('foo', 'bar')
You use INSERT ... EXEC to push the result of the procedure into a table (can be a temp #table or a #table variable), the you open the cursor over this table. The article in the link discusses the problems that may occur with this technique: it cannot be nested and it forces a transaction around the procedure.
You could execute your SP into a temporary table and then iterate over the temporary table with the cursor
create table #temp (columns)
insert into #temp exec my_stored_proc ....
perform cursor work
drop table #temp