I have a stored procedure which returns back a table value.
Here is my stored procedure:
PROCEDURE [GetPermitPendingApproval]
#permitYear int = NULL,
AS
BEGIN
SELECT [p].[ID]
,[p].[PermitNumber]
,[p].[PermitTypeID]
,[p].[ApplicationDate]
,[u].[FirstName]
,[u].[MI]
,[u].[LastName]
,[u].[Suffix]
,[u].[ProfessionalTitle]
,[u].[WorksFor]
FROM [SciCollUser] u
INNER JOIN UserPermit up ON up.[UserID] = u.[ID]
INNER JOIN Permit p ON p.[ID] = [up].[PermitID]
WHERE (#permitYear IS NULL OR p.PermitYear = #permitYear)
ORDER BY [p].[ApplicationDate] ASC;
END
I am not sure whether we have such a way to use PetaPoco to execute a stored procedure and get a returned data as a table? Please help!
As normally I can execute a stored procedure with the follow script but it is not the way I want.
db.Execute("EXEC GetPermitPendingApproval #permitYear=2013");
You need to put a semicolon before EXEC.
var result = db.Fetch<dynamic>(";EXEC GetPermitPendingApproval ##permitYear = #0", 2013);
Answer is probably late, but I hope, that it will be useful for future generations. You should turn EnableAutoSelect option to false on PetaPoco database object db.EnableAutoSelect = false;
Otherwise it will keep adding SELECT NULL FROM [Object] to you sql statement.
It's good, that it's possible to debug PetaPoco sources.I've found this option only because of debugging!
You get List<T> where T is a POCO type with the properties you want to map or a Dynamic
So the actual syntax is:
var result = db.Fetch<dynamic>(";EXEC GetPermitPendingApproval #0", 2013);
or
var result = db.Fetch<dynamic>(";EXEC GetPermitPendingApproval #permitYear",
new {permitYear = 2013});
As of v6.0.344-beta, PetaPoco now supports stored procs natively, so you can do:
var result = db.FetchProc<MyClass>("GetPermitPendingApproval", new { permitYear = 2013 });
Related
I am referring Using dynamic query in Liferay and using MySQL 5.5 but instead of custom queries involving multiple entities,we need to call a stored procedure.
We have created a sample procedure
delimiter //
Create Procedure proc_check (OUT count INT)
begin
select count(*) into count from lg_office ;
end//
In default.xml,containing custom queries,we have used
<sql id="de.uhh.l2g.plugins.service.persistence.ProducerFinder.findOfficeCount">
<![CDATA[
Call proc_check(#output)
]]>
</sql>
In the respective Finder method,we used the below snippet to call the stored proc,passing -1 for both begin and end.
String sql = CustomSQLUtil.get(FIND_OFFICE_COUNT);
SQLQuery q = session.createSQLQuery(sql);
QueryPos qPos = QueryPos.getInstance(q);
//qPos.add(lectureseriesId);
List <Integer> sl = (List<Integer>) QueryUtil.list(q, getDialect(), begin, end);
return sl;
In QueryUtil,we could not find other applicable methods to execute the call.
Post this we get the below error
ERROR [RuntimePageImpl-5][JDBCExceptionReporter:82] ResultSet is from UPDATE. No Data.
Is this approach correct with something missing or if not,please suggest approach to achieve the same.
there isn't any utility built-in in liferay to call stored procedure but you can just get the connection with DataAccess.getConnection(); and use the jdbc api like this way
Connection connection =DataAccess.getConnection();
CallableStatement cs = connection.prepareCall("{Call proc_check(#output)}");
ResultSet rs = cs.executeQuery();
Look at this, try it.
session = openSession();
String sql = CustomSQLUtil.get(DELETE_BY_PROJETID);
SQLQuery query = session.createSQLQuery(sql);
query.setCacheable(false);
QueryPos qPos = QueryPos.getInstance(query);
qPos.add(projectId);
query.executeUpdate();
https://web.liferay.com/it/community/forums/-/message_boards/message/37490823
How can I call a stored procedure in Acumatica via PXDataBase which has as input parameter User defined type?
For example, I have the following type:
CREATE TYPE [dbo].[string_list_tblType] AS TABLE(
[RefNbr] [nvarchar](10) NOT NULL,
PRIMARY KEY CLUSTERED
(
[RefNbr] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
I have the following stored procedure:
CREATE PROCEDURE [dbo].[GetListOfAPInvoices]
#APInvoices as string_list_tblType readonly,
AS
BEGIN
select * from APInvoice a where a.RefNbr in (select RefNbr from #APInvoices)
END
and following fragment of C# code:
var par = new SqlParameter("APInvoices", dt);
par.SqlDbType = SqlDbType.Structured;
par.TypeName = "dbo.string_list_tblType";
par.UdtTypeName = "dbo.string_list_tblType";
par.ParameterName = "APInvoices";
PXSPParameter p1 = new PXSPInParameter("#APInvoices", PXDbType.Udt, par);
var pars = new List<PXSPParameter> { p1};
var results = PXDatabase.Execute(sqlCommand, pars.ToArray());
but when I execute my C# code I'm receiving error message:
UdtTypeName property must be set for UDT parameters
When I debugged with reflector class PXSqlDatabaseProvider, method
public override object[] Execute(string procedureName, params PXSPParameter[] pars)
I noticed that
using (new PXLongOperation.PXUntouchedScope(Thread.CurrentThread))
{
command.ExecuteNonQuery();
}
command.Parameters.Items has my method parameters, but item which is related to Udt type is null. I need to know how to pass user defined table type. Has anybody tried this approach?
Unfortunately UDT parameters are not supported in Acumatica's PXDatabase.Execute(..) method and there is no way to pass one to a stored procedure using the built-in functionality of the platform.
Besides, when writing data-retrieval procedures like the one in your example, you should acknowledge that BQL-based data-retrieval facilities do a lot of work to match company masks, filter out records marked as DeletedDatabaseRecord and apply some other internal logic. If you chose to fetch data with plain select wrapped into a stored procedure you bypass all this functionality. Hardly is this something that you want to achieve.
If you absolutely want to use a stored procedure to get some records from the database but don't want the above side-effect, one option is to create an auxiliary table in the DB and select records into it using a procedure. Then in the application you add a DAC mapped to this new table and use it to get data from the table by means of PXSelect or similar thing.
Coming back to your particular example of fetching some ARInvoices by the list of their numbers, you could try using dynamic BQL composition to achieve something like this with Acumatica data access facilities.
I have created a mvc4 application with entity framework. Added a entity model in project. Now i have
added a store procedure in model browser and editing import function. There is a option Returns a collection of which contains none,scalers,complex,entities. I am not able to decide which one to choose as my store procedure returns multiple output parameters. If it returns single parameter then i can choose scalers, if table then entities. But it returns more then one output parameter so which one to choose. I am attaching store procedure screen shot.
Your stored procedure uses reference parameters, but doesn't actually return anything. To make a stored procedure return something, end the procedure with a SELECT statement that doesn't set a variable.
So, your code with look something like this:
CREATE PROC [wickedbrains].[uspValidateAdminLogin]
#UserName VARCHAR(50),
#Password VARCHAR(50)
AS
BEGIN
DECLARE #UserId INT = NULL,
#Res INT = 0;
IF EXISTS(SELECT '' FROM tblAdminUser WHERE UserName = #UserName AND Pwd = #Password)
BEGIN
SELECT #UserId = Id FROM tblAdminUser WHERE UserName = #UserName AND Pwd = #Password;
SET #Res = 1;
END
SELECT #UserId, #Res;
END
Once you've fixed your stored procedure, as Ehsan described, you can fix your imported stored procedure after the fact by clicking Get Column Information, then clicking Create New Complex Type.
If you absolutely have to use output parameters, you will have to retrieve the parameters with code as you would with reference parameters used in any other function. The point is that stored procedures that only use output parameters don't have a return type. See this answer for further details: https://stackoverflow.com/a/6193419/12116036
I tried implementing a call to Stored proc and the proc returns ID which will used later.
Everytime I execute I get the out parameter as -1. Below is my sample code:
OleDbCommand sqlStrProc = new OleDbCommand();
sqlStrProc.Connection = dbConn;
sqlStrProc.CommandText = "dbo.insert_test";
sqlStrProc.CommandType = CommandType.StoredProcedure;
sqlStrProc.Parameters.Add("#p_TestID", OleDbType.Integer, 255).Direction = ParameterDirection.Output;
sqlStrProc.Parameters.Add("#p_TestName", OleDbType.VarChar).Value = "Test";
sqlStrProc.Parameters.Add("#p_CreatedBy", OleDbType.VarChar).Value = "Test";
int personID = sqlStrProc.ExecuteNonQuery();
Row.outPersonID = personID;
personID is always -1. What am I doing wrong here. Please help..!!
Below is the stored proc code
CREATE PROCEDURE [dbo].[INSERT_TEST]
#p_TestID int OUTPUT,
#p_TestName varchar (50),
#p_CreatedBy varchar (100)
AS
SET NOCOUNT ON
INSERT INTO Test(
TestName,
CreatedBy)
VALUES
( #p_TestName,
#p_CreatedBy)
SELECT #p_TestID = SCOPE_IDENTITY()
-1 could mean that the stored procedure failed to execute as desired and the transaction was rolled back. You may want to look for any truncation issues since you have different sizes for the 2 input parameters but are using the same input. Also I assume you have proper code to open and close connections etc?
-1 returned value is an error produced during the execution of your SP, this is due to the following reasons:
SP Structure: everytime you are executing the SP it tries to create it again while it already exists. so you have to either make it an ALTER PROCEDURE instead of CREATE PROCEDURE or do the following:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[INSERT_TEST]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[INSERT_TEST]
GO
CREATE PROCEDURE [dbo].[INSERT_TEST]
#p_TestID int OUTPUT,
#p_TestName varchar (50),
#p_CreatedBy varchar (100)
AS
Database Connection (Table Name and Location): you have to specify withe the OLEDB the ConnectionString that connects you to the write DB. try to test the full Table path; like the following;
INSERT INTO [DATABASENAME].[SHCEMA].[TABELNAME](
Name,
CreatedBy)
VALUES
( #p_TestName,
#p_CreatedBy)
Define your SP as :
CREATE PROCEDURE [NAME]
AS
BEGIN
END
thought it is not a problem, but it is a proper way to write your SPs in terms of connection transactions,
Let me know if it works fine with you :)
Regrads,
S.ANDOURA
Simple question, as the title suggests:
What is the syntax to drop a Stored Procedure (SP) in SQL Server 2000, by first checking that the SP exists?
Please provide the full code.
Microsoft recommended using the object_id() function, like so:
IF EXISTS (select * from dbo.sysobjects where id = object_id(N'[dbo].[YourProcedure]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
DROP PROCEDURE [dbo].[YourProcedure]
GO
.
object_id() helps resolve owner conflicts. If you do
SELECT name FROM sysobjects WHERE name = 'my_procedure'
, you may see many different procedures with the same name -- all for different owners.
But, SELECT * FROM sysobjects WHERE id = object_id(N'[my_procedure]') will only show you the one for the current owner/user, if more than one procedure by that name exists.
Still, always specify the object owner (default is dbo). Not only does this avoid nasty side-effects, it's a little faster too.
Not for SQL Server 2000, but starting with SQL Server 2016, you can use the IF EXISTS syntax:
DROP PROCEDURE IF EXISTS [sp_ProcName]
A slightly simpler method without going to system tables:
IF OBJECT_ID('my_procedure') IS NOT NULL DROP PROCEDURE my_procedure
GO
Like this:
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'my_procedure' AND type = 'P')
DROP PROCEDURE my_procedure GO
Hope that helps!
You can do the following if you want to remove multiple Procedures.
NB: This syntax works on SQL Server 2016 and later
USE [Database_name]
GO
BEGIN
DROP PROCEDURE IF EXISTS 'my_procedure1',
'my_procedure2',
'my_procedure3',
'my_procedure4',
'my_procedure5',
END
In SQL SERVER 2008, if you want to drop a stored procedure just write the below command....
DROP PROC Procedure_name
DROP PROC dbo.spInsertUser
Hope it helps..