Does BLT support Oracle stored procedures? I've tried numerous methods, described below to get it to work but no luck. The stored procedure updates a table with several values. This is the stored procedure, a small test procedure.
DROP PROCEDURE BETA_AUTO_UPDATE;
/
CREATE OR REPLACE PROCEDURE BETA_AUTO_UPDATE
(
AutoId IN NUMBER,
Rule IN NVARCHAR2,
Nam IN NVARCHAR2,
Loc IN NVARCHAR2
)
IS
BEGIN
UPDATE Beta_Auto
SET RuleGuid = Rule,
Name = Nam,
Location = Loc
WHERE Id=AutoId;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001, 'ERROR OCCURED DURING UPDATE');
END BETA_AUTO_UPDATE;
/
Tried the following
DbManager.AddDataProvider(new OdpDataProvider());
DbManager OracleDb = new DbManager("BetaOracleDBConn");
Beta_Auto Betar = new Beta_Auto();
Betar.ID = 1;
Betar.Name = "Jim";
Betar.RuleGuid = "jlDKDKDKDKDKDKp";
Betar.Location = "LocDLDLDLDLDtor";
OracleDb.SetSpCommand("Beta_Auto_UPDATE",
OracleDb.CreateParameters(Betar)).ExecuteNonQuery();
That didn't work.
Tried this
[ActionName("UPDATE")]
public abstract void Update(Beta_Auto Auto);
That didn't work.
Tried this:
[SprocName("Beta_Auto_Update")]
public abstract void UpdateByParam(
[Direction.InputOutput("ID", "RuleGuid", "Name", "Location")] Beta_Auto Auto);
That didn't work.
[SprocName("Beta_Auto_Update")]
public abstract void UpdateByParam(int Id, string RuleGuid, string Name, string Location);
Also tried this:
[ActionName("Update")]
public abstract void UpdateByParam(int Id, string RuleGuid, string Name, string Location);
That didn't work.
Set the trace level on odp.net to 7. Saw that the call was being made, but couldn't see any parameters. Swapped out XE (thought it might have been a licensing problem as db was bigger that 5GB) for enterprise Oracle. Didn't work.
Create a new user, datafile, tablespace, and assigned all roles and privs, including Execute Any Procedure to the user. Didn't work.
I ran a standard ado.net (very long winded) to call the stored procedure via OracleCommand and it called perfectly and did the update.
I am stumped. All of the above work for SQL Server.
Thanks.
scope_creep
I'm doing it like
var parameters = OracleDb.GetSpParameters("BETA_AUTO_UPDATE", true, true);
parameters.SetParamValue("pParam1", param1);
parameters.SetParamValue("pParam2", param2);
...
OracleDb.SetSpCommand("BETA_AUTO_UPDATE", parameters).ExecuteNonQuery();
It's an extra round-trip, but since I'm only using stored procedures for a couple of big batch updates it doesn't really matter, (normal/simple updates are done with Linq DML operations)
Related
I have installed EF Core 5 Power Tools to Add a DB with stored procedure to an ASP.NET Core project. the models are successfully generated by Power Tools and the tables work fine; but when i try to retrieve a result set out of a stored procedure and store it to a ViewBag to display on the View, the value stored at Viewbag is weird and has nothing to do with a result set.
Here is the stored procedure code at db, which is pretty simple, just to test Power Tools:
CREATE PROCEDURE retTable (#P INT)
AS
BEGIN
SELECT * FROM STU WHERE ID=#P;
END;
Controller:
public IActionResult Index()
{
schoolContext s = new schoolContext();
schoolContextProcedures sp = new schoolContextProcedures(s);
var t = sp.retTableAsync(20); // The built is perfectly done, but the value store instead of result set is weird
ViewBag.test = t;
return View();
}
and just added a #View.Bag to the view to make sure it's displayed, Though the app's built is done successfully without any error, This is what's displayed at the View instead of ViewBag value:
System.Runtime.CompilerServices.AsyncTaskMethodBuilder1+AsyncStateMachineBox1[System.Collections.Generic.List`1[WebApplication2.Models.DB.retTableResult],WebApplication2.Models.DB.schoolContextProcedures+d__3]
Tried to convert the result set to a list or something else but it's not working :|
Anyone know how to fix it?
The value stored in it is not "weird", its a Task.
Since your method is async, you should await for the result of the returned task, not the "return" itself, as this is only a reference to the task that is executed asynchronusly.
As martin smith mentions, just:
var t = await sp.retTableAsync(20);
Otherwise you are adding a task as the viewbag property, instead of the task result once completed
I have one Stored Procedure with different actions in it. For Eg - Insert, select, update all are in one stored procedure and I execute it using a if else condition.
BEGIN
if(#type = 'add')
INSERT INTO [dbo].[napme]
([firstname]
,[lastname]
,[Address]
,[City])
VALUES
(#firstname,#lastname,#Address,#City)
if(#type = 'select')
select * from napme
END
Now can I use that procedure in MVC using Entity Framework. If so how?
Once such method is mapping the parameters but I am unable to map #type
Can anyone suggest any easy way
You can try like this
var courseList = ctx.Database.SqlQuery<YourEntityName>("exec ProcName #Param1", Param1).ToList<YourEntityName>();
If you plan on using Code-First EntityFramework then you can map Insert, Update and Delete operations to stored procedures if you wish.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Entity<YourEntityClass>()
.MapToStoredProcedures();
}
With a SP example like so:
CREATE PROCEDURE [dbo].[YourEntityClass_Insert]
#param1 nvarchar(max),
#param2 nvarchar(max)
AS
BEGIN
INSERT INTO [dbo].[YourEntityClass] ([col1], [col2])
VALUES (#param1, #param2)
Look here for more information.
If you plan on executing a SP for other reasons (non CRUD) then you will have to execute a SP as per bharats answer.
I have requirement like to call the stored procedures to get the data, here i will get the stored procedure name through post data.
I tried using GString but no use, Can any one help me to solve this issue.
Thanks in advance.
This is a weird one, but possible. Grails/GORM doesn't provide a way to execute stored procedures. It's just not part of ORM functionality. And neither does Hibernate. But, Hibernate does provide access to a JDBC connection. So you can get a connection from Hibernate, then create a Groovy Sql instance with the connection, and finally execute your stored procedure. Here's an example:
import groovy.sql.Sql
SomeDomainClass.withNewSession { session ->
session.doWork { java.sql.Connection connection ->
def sql = new Sql(connection)
sql.call("YOUR STORED PROCEDURE SQL HERE")
}
}
It works like this:
Using any of your domain classes, call withSession(Closure) to get a Hibernate session.
With the session, call doWork(Work) to get access to the session's JDBC connection. Now, doWork(Work) expects an implementation of org.hibernate.jdbc.Work. But, if I recall correctly, Groovy can take a closure with the same parameters and coerce it to implement the interface.
Using the connection, create an instance of Sql. You could skip this and query with Java, but Groovy's Sql class is so nice.
Use one of the available Sql.call() methods to execute your stored procedure.
In postgress SQL, it is posible to call stored procedure. The catch is returning a data table so that you can map it to a model. This is as shown bellow.
create function activate(confirmationcode text)
returns TABLE(resultid integer, resultmessage character varying)
language plpgsql
as $$
BEGIN
....
END
This can be invoked as follows in GORM db connections
type FuncResult struct {
Resultid int
Resultmessage string
}
...
fResult := FuncResult{}
err := s.db.Raw("SELECT * from activate(?)", token).Scan(&fResult).Error
I am new to dropwizard. I am going through different tutorial but I couldnt find good example/tutorial on how to call stored procedure in dropwizard using JDBI.
With JDBI it is possible to specify an object SQL query as a method annotation. This string is treated by the DB as normal SQL. An example DAO to execute a stored procedure might look like:
public interface SomeQueries
{
#SqlQuery("call find_name_procedure(:id)")
String findName(#Bind("id") int id);
}
Where find_name_procedure has been previously defined.
For more information see http://jdbi.org/sql_object_api_queries/
Jooq is an elegant way to call stored procedures from java (See https://dzone.com/articles/using-stored-procedures-with-jpa-jdbc-meh-just-use). You also have a thirdparty module integrating Jooq into Dropwizard
(See http://modules.dropwizard.io/thirdparty/)
So if you're familiar with Maven, you can set up the combination quickly and start validating if it works in your case.
DropWizard JDBI provides two options to make a stored procedure call. Depending on what you want from Stored proc.
If you want resultset from Stored Proc, Andy has answered that already:
public interface DAO
{
#SqlQuery("call sp_name(:id)")
String query(#Bind("id") int id);
}
The other scenario is that your stored proc doesn't return resultset but gives out some output parameters. Here is what you can do:
#SqlCall("{ CALL sp_name(:id, :id2) }")
#OutParameter(name = "out", sqlType = Types.INTEGER)
OutParameters spCal(#Bind("id") long id, #Bind("id2") long id2);
OutParameter annotation may not work in DropWizard as the annotation was introduced in v3, you can use the following for accessing OutParameters:
try (Handle handle = dbi.open()) {
parameters = handle.createCall("CALL sp_name(:IN_Field1,:OUT_field2)")
.bind("IN_Field1", filed1)
.registerOutParameter("OUT_field2", Types.INTEGER)
.invoke();
}
And for some real freaky situations where you will need both Outparameters and resultset - DropWizard currently doesn't provide any direct way (Because the JDBI version with dropwizard is old). So, you can get connection by doing below:
handle = jdbi.open()
handle.getConnection()
And then do what you want to do with the connection.
Also, one more thing - I will not try to use Hibernate for Stored Proc call. Its just more pain.
I used Zalando Sprocwrapper. I like it and was widely used in the Zalando company to call PostgreSQL functions.
https://github.com/zalando-incubator/java-sproc-wrapper
I'm trying to design a small CRUD tool, and so far every facet (the Rich Faces UI and Managed Beans,
validation, the mySQL database, etc.) is going fine, but not the myBatis piece.
I'm relatively new to myBatis and am keeping the users guide and API close at hand, but there
are still some things that just won't come together for me, and one is any call to a procedure
involving multiple IN parameters. Here is an example:
This from the DB set up scripts:
create procedure MY_FOO_PROC (IN valA VARCHAR(15), IN valB CHAR(1))
begin
select blah from blah where blah = valA and blah = valB etc.;
end
This from MyMapper.java:
public interface MyMapper {
List<MyFooClass> getProgress (
#Param("valA") String valueA, #Param("valB") String valueB);
}
This from MyMapper.xml:
<select id="getProgress" parameterType="map"
resultMap="MyFooMap" statementType="CALLABLE">
{ call MY_FOO_PROC (
#{valA, mode=IN, jdbcType=VARCHAR}
#{valB, mode=IN, jdbcType=CHAR}
)}
</select>
And finally this from my DAO class:
public static List<MyFooClass>
doGetProgress (String valueA, String valueB) {
SqlSession session = MyBatisConnectionFactory.getInstance().getSqlSessionFactory().openSession();
EsparMapper mapper = session.getMapper(MyMapper.class);
List<MyFooClass> listFoo = mapper.getProgress(valueA, valueB); // line which originates exception below
session.close();
return listFoo;
}
The result:
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect number of arguments for PROCEDURE dbname.MY_FOO_PROC; expected 2, got 1
### The error may involve my.package.names.getProgress-Inline
### The error occurred while setting parameters
I will note that I have also tried:
creating a POJO with variables valA and valB and getters/setters for
each,
making parameterType="PojoClass" in the XML,
skipping the session.getMapper() and creating an instance of PojoClass,
and calling session.selectList("getProgress", pojoInstance);
with the nearly identical result (i.e. wrong number of arguments).
Very little help on net search, most telling me to do what I think I have already done.
I think you're missing a comma in the procedure call.
<select id="getProgress" parameterType="map"
resultMap="MyFooMap" statementType="CALLABLE">
{ call MY_FOO_PROC (
#{valA, mode=IN, jdbcType=VARCHAR} , --<--- this
#{valB, mode=IN, jdbcType=CHAR}
)}
</select>