create procedure pro_training2
as
begin
create view Tab1view As
select * from tab1
end
Is this possible to create a view in the procure?
You can do this using dynamic SQL, e.g.
CREATE PROCEDURE dbo.pro_training2
AS
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'CREATE VIEW dbo.Tab1View AS SELECT <columns> FROM dbo.tab1;';
EXEC sp_executesql #sql;
END
GO
But this is a serious code smell.
You have tagged with MySQL though the above is not MySQL syntax.
Anyway, if you did mean for MySQL: yes, it is possible to issue CREATE VIEW from within a procedure, but using a different syntax:
CREATE PROCEDURE pro_training2()
MODIFIES SQL DATA
BEGIN
create view Tab1view As select * from tab1;
END
Use sp_executesql and specify the Database name:
EXEC myDb1..sp_executesql N'CREATE VIEW Tab1view As select * from tab1'
Related
In my project I have defined a stored procedure with a example code below:
CREATE PROCEDURE [dbo].[Stored]
#ParameterA AS varchar(128),
#ParameterB AS varchar(128),
#ParameterC AS varchar(400)
AS
BEGIN
DECLARE #query AS Varchar(MAX)
SET #query = 'SELECT *
FROM Table
WHERE A = '''+ #ParameterA + ''
IF #ParameterB = 'B'
BEGIN
SET #query = #query + ' AND C=''' + #ParameterC + ''
END
EXECUTE sp_executesql #query
END
I call this procedure with Entity Framework through the following code:
DBContext.Database.SqlQuery<Object>("Stored",
new SqlParameter("#p0", Param0),
new SqlParameter("#p1", Param1),
new SqlParameter("#p2", Param2)).ToList();
If I call a stored procedure with the string below, I generate a SQL injection:
Param2 = "ABC' ; DROP TABLE Table2"
How can I prevent this with Entity Framework?
You cannot
The underlying SQL procedure is faulty and a security nightmare. There is no way you can repair that on the layer on top of it. You are doing the best you can in EntityFramework, but it's still unsafe. You need to repair the problem (SQL proc) and not apply band aids to the layer using it.
sp_executesql seems to be a good starting point for a procedure that needs to have dynamic SQL and bind parameters.
you are creating a dynamic query, where you are concatenating parameters. this is causing issue.
do not use dynamic query, or validate parameters (if it contains any keywords or characters)
you can also rewrite your query into IF-ELSE structure on basis of parameters, so you do not need dynamic query.
I am trying to get the content a table with a dynamic SQL stored procedure called from the database context object (using Entity Framework 6.1.1), in order to populate a GridView control. I fail to retrieve the data.
Here's the stored procedure. It is for a student demonstration about SQL injection in stored procedures, so I KNOW this is inject-able and it's fine.
ALTER PROCEDURE dbo.SearchProducts
#SearchTerm VARCHAR(max)
AS
BEGIN
DECLARE #query VARCHAR(max)
SET #query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + #SearchTerm + '%'''
EXEC(#query)
END
The C# code behind I then use to execute the stored procedure is :
var db = new MyEntities();
var TEST_SEARCH_TERM = "product";
var result = db.SearchProducts(TEST_SEARCH_TERM);
MyGridView.DataSource = result;
MyGridView.DataBind();
When executed, in the Database Explorer in Visual Studio, the stored procedure works fine. But when executed in the running ASP.NET app, I get an exception in the DataBind() method because result returns -1 instead of an IEnumerable DataSet containing the objects resulting from the stored procedure's SELECT.
How can I retrieve the data and populate my GridView?
Use the following steps to solve this issue:
You need to Import the stored procedure as a Function. Right-click on the workspace area of your Entity model and choose Add -> Function Import.
In the Add Function Import dialog, enter the name you want your stored procedure to be referred to in your model for example Search_Products, choose your procedure from the drop down list, and choose the return value of the procedure to be Entities and choose Products from the drop down list.
Then in the code behind:
var db = new MyEntities();
var TEST_SEARCH_TERM = "product";
var result = db.Search_Products(TEST_SEARCH_TERM);//Search_Products is the name that you specified in Function Import dialog
MyGridView.DataSource = result;
MyGridView.DataBind();
The reason that you get -1 for result is that Entity Framework cannot support Stored Procedure Return values out of the box. I think support of stored procedure return values depends on version of Entity framework. Also Entity Framework doesn't have rich stored procedure support because its an ORM, not a SQL replacement.
I have come across this before with stored procedures using dynamic SQL. I have had success using complex types if I add the line 'SET FMTONLY OFF;' (see https://msdn.microsoft.com/en-us/library/ms173839.aspx) to the top of my stored procedure before it is added to the EF model. Once you have your model setup with your complex type, be sure to remove this line.
Example:
ALTER PROCEDURE dbo.SearchProducts
#SearchTerm VARCHAR(max)
AS
BEGIN
SET FMTONLY OFF;
DECLARE #query VARCHAR(max)
SET #query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + #SearchTerm + '%'''
EXEC(#query)
END
Verify that your EDMX has a return type:
Go to Function Imports --> SearchProducts, and double click it.
In order to utilize a Complex return type, Entity Framework will require that you explicitly define column names in your stored procedure instead of using *.
Once your stored procedure is modified to define the column names, you can update your model in the project. (Note, performing a complete drop of the SP, and then adding it back to your edmx may be the best route.)
EDIT
Maybe you can modify your SP like the following:
ALTER PROCEDURE dbo.SearchProducts
#SearchTerm VARCHAR(max)
AS
BEGIN
SELECT * FROM dbo.Products WHERE Name LIKE '%' + #SearchTerm + '%'
END
You seem to have sorted your problem out, there is official documentation from Microsoft available at the links below:
How to import a stored procedure into your entity data model:
https://msdn.microsoft.com/en-us/library/vstudio/bb896231(v=vs.100).aspx
Complex types in the EF designer:
https://msdn.microsoft.com/en-gb/data/jj680147.aspx
Make sure you are working with the latest version of .net and you keep your model up to date when you make changes to your database.
I am using the following technologies:
MS SQL 2008 R2
Visual Studio 2010
Silverlight project
LINQ to SQL
When dragging a stored procedure into the data model, and the stored procedure returns an OUTPUT parameter, it works fine. However when the stored procedure returns a result set created with dynamic SQL I receive the following error:
"Unknown Return Type, The return type for the following stored procedure could not be detected."
If the stored procedure does not use dynamic SQL, it works fine.
(For example: SELECT column1 from table2)
The stored procedure however uses dynamic SQL to query a specified view for the data. Simplified below for illustration purposes:
CREATE PROCEDURE GetViewData
#ViewName nvarchar(150)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql nvarchar(MAX)
SET #Sql = 'SELECT Column1, Column2, Column3 FROM' + #ViewName
EXEC sp_executesql #Sql
END
Instead of returning the result set directly, I can place the result set into a temp table. This however gives the same error.
According to the article from Ritesh, when placing the result set into a table type variable this should do the trick, however this is not possible in dynamic sql as the scope is only within the executed dynamic sql.
Ritesh's article:
http://riteshkk2000.blogspot.com/2010/08/error-unknown-return-type-return-types.html
Upon further investigation I realized that the meta data received by LINQ to SQL does not contain the necessary information to define the type.
Apparently with SQL 2012 this can be resolved by using "WITH RESULTS SET" to actually define the meta data manually.
I resolved this by creating another stored procedure, calling GetViewData without using dynamic SQL and populating a table type variable:
CREATE PROCEDURE CallGetViewData
#ViewName nvarchar(150)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ViewResultSet TABLE
(
column1 nvarchar(50),
column2 int,
column3 float
)
INSERT INTO #ViewResultSet
EXEC GetViewData #ViewName
SELECT column1, column2, column3 FROM #ViewResultSet
END
Now when I drag stored procedure CallGetViewData into the data model, it detects the return type correctly.
One trick you can try is to manually create a model that represents the shape of the object that the Stored Proc will return. Then using the designer, don't drag the proc into the method pane, but rather drop it on the type you created manually. LINQ to SQL will then use that class as the result type.
If you already have the method defined for the stored proc, you can change the Return Type using the F4 property window to any type that matches the result shape that you've defined in the model.
I have various stored procedures. I need a stored procedure to execute a stored procedure and then return only the row count (number of returned rows by the called procedure) and I need to receive it in c# code.
What's the best way to do this?
Assuming you are using SQL Server (which is possible from the code snippets), perhaps something like this would work for you:
exec('exec <your stored procedure goes here>; select ##RowCount')
Since you are running SQL Server, I can think of one solution that is not necessarily pretty.
Create a temporary table (table variable if you have a more recent version of SQL Server). Then execute:
exec(`
declare #t table (
<columns go here>
);
insert into #t
exec(''<your exec here>'');
select #rowcount
');
And now that I've said that, I would recommend sp_executesql. This goes something like this:
declare #sql nvarchar(max) = N'exec '+#YOURQUERY + '; set #RowCount = ##RowCount';
exec sp_executesql #sql, N'#RowCount int output', #RowCount = RowCount output;
I spent most of yesterday debugging an arcane condition that arises when you call a stored procedure inside an insert.
You can try this in your child stored procedure :
CREATE PROC PawanXX
(
#a INT
,#b INT OUTPUT
)
AS
BEGIN
SELECT TOP 2 * FROM X
SET #b = ##ROWCOUNT
RETURN #b
END
GO
The main stored procedure where we call all other sps
DECLARE #RC int
DECLARE #a int
DECLARE #b int
EXECUTE #RC = [dbo].[PawanXX]
#a
,#b OUTPUT
SELECT #RC
The output for the same
ProcessName Parent Child
ShareDrafts Job12 Job03
ShareDrafts Job13 Job58
(2 row(s) affected)
2
(1 row(s) affected)
I want to use LINQ to call stored procedure in this way but stored procedure I want to call contain SQL string that executed by
EXEC sp_executesql #strSQL
In this way Visual Studio does not generate result class. To resolve this problem I execute SQL string by
INSERT INTO #Temp EXEC sp_executesql #strSQL
SELECT * from #Temp
Maybe it is not the best way but it works. The problem is that it sometimes return items in wrong sequence. How to fix it?
Use an Order By to specify the sort order