How can I call a stored procedure using Groovy?
How can I create a stored procedure from Grails project (as domain classes to create data base)?
An example of calling a FullName stored procedure which takes a param ('Sam' in the example) and returns a VARCHAR.
sql.call("{? = call FullName(?)}", [Sql.VARCHAR, 'Sam']) { name ->
assert name == 'Sam Pullara'
}
The same example again but with a GString variation:
def first = 'Sam'
sql.call("{$Sql.VARCHAR = call FullName($first)}") { name ->
assert name == 'Sam Pullara'
}
Here is an example of a stored procedure with an out parameter:
sql.call '{call Hemisphere(?, ?, ?)}', ['Guillaume', 'Laforge', Sql.VARCHAR], { dwells ->
println dwells // => Northern Hemisphere
}
Refer this.
Related
In my code I call stored procedure like this (and it works perfectly):
{ ? = call schema.package.function(?) }
I need to call it like this because jdbc connection is set to another schema.
But for now I can't test it because H2 database doesn't support packages. So if I change my jdbc url database name to the one I require and delete "schema" from the call everything is ok while testing.
#Test
fun test() {
val session = em.entityManager.unwrap(Session::class.java)
session.doWork {
val st = it.createStatement()
st.execute("create schema if not exists mySchema")
st.execute("create alias mySchema.myPackage.myFunction for " // the error happens here +
"\"${this.javaClass.name}.myFunction\"")
}
val response = dao.myFunction("1")
//test stuff
}
How can I change my test because now it's giving me the syntax error?
I am trying to create a method that call Stored Procedure to do a very easy insert and a select,
I created a stored procedure on an Oracle database as below:
CREATE OR REPLACE PROCEDURE schema.insertNewTable(p_test IN VARCHAR2, p_out OUT VARCHAR2)
IS
BEGIN
INSERT INTO NEWTABLE("TEST") VALUES(p_test);
SELECT '1' INTO p_out FROM DUAL;
COMMIT;
END;
Then on an Entity:
#Procedure(procedureName = "insertNewTable", outputParameterName="p_out")
String insertNewTable(#Param("p_test") String p_test);
but everytime i call this method i get this:
2018-06-23 20:04:43,047|ORA-06550: row 1, colonna 7:
PLS-00306: wrong number or types of arguments in call to 'INSERTNEWTABLE'
ORA-06550: riga 1, column 7:
PL/SQL: Statement ignored
2018-06-23 20:04:43,100|org.springframework.dao.InvalidDataAccessResourceUsageException: Error calling CallableStatement.getMoreResults; SQL [insertNewTable]; nested exception is org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:261)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:503)
After a couple of tries (and exceptions), I modified the Entity and the call to avoid "OUT" types and, in this way, I have no errors:
CREATE OR REPLACE PROCEDURE schema.insertNewTable(p_test IN VARCHAR2)
IS
BEGIN
INSERT INTO NEWTABLE("TEST") VALUES(p_test);
COMMIT;
END;
Then on an Entity:
#Procedure(procedureName = "insertNewTable")
void insertNewTable(#Param("p_test") String p_test);
How can i fix this to get a return value?
with Spring DATA
in your repository:
1) calling with native SQL :
#Query(value = "select Store-procedure-name(:param) from dual", nativeQuery = true)
BigDecimal method-name(#Param("param") Long param);
2)
#Procedure(procedureName = "store-procedure-name", outputParameterName = "output-param-of-store-procedure")
return-type-of-store-procedure method-name(input-params-of-store-procedure);
you can use NamedStoredProcedureQuery
#NamedStoredProcedureQuery(
name = "insertNewTable",
procedureName = "insertNewTable",
parameters = {
#StoredProcedureParameter(mode = ParameterMode.IN, type = String.class, name
= "p_test"),
#StoredProcedureParameter(mode = ParameterMode.OUT, type = String.class, name
= "p_out"),
)
}
)
method call:
StoredProcedureQuery query =
this.em.createNamedStoredProcedureQuery("insertNewTable");
query.setParameter("p_test", ""TEST"");
query.execute();
String out = query.getOutputParameterValue("p_out");
I am looking forward to know how can I run an Azure SQL stored procedure with multiple input parameters from Nodejs.
For example, if I have a stored procedure FIND_USERS(activity_status, color, gender) which runs a query
select * from users where isActive = activity_status and bay_color = color and userGender = gender;
I should be able to call this stored procedure from nodejs with the input parameters. The thing to understand here is that I want have a SQL transaction service that can take any CALL PROCEDURE type command along with the set of input parameters and call the procedure using those input parameters irrespective of the number of input parameters.
What I know is that for MySQL, there is a mysql library which lets me run procedures with multiple parameters. I have encapsulated it in MySQLConnector.js service as
var mysql = require('mysql');
exports.query = function(sql, values, next) {
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection({
host:host,
user:user,
password:password,
database:database
});
connection.connect(function(err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
console.log(err == 'Error: ER_CON_COUNT_ERROR: Too many connections')
if(err == 'Error: ER_CON_COUNT_ERROR: Too many connections'){
connection.end();
}
}
});
connection.query(sql, values, function(err) {
connection.end();
if (err) {
throw err;
}
next.apply(this, arguments);
});
}
With this, I can call a stored procedure from nodejs with a function like
MySQLConnector.query('CALL FIND_USERS (?, ?, ?)', [1, 'blue', 'female'], function(err, userData) {
//do something with userData
});
How is it possible to do this for Azure MS SQL?
You can use tedious driver to connect to SQL Server. It supports both input+output parameter for statements and SPs, you can find the example in http://tediousjs.github.io/tedious/parameters.html
Feels free to raise an issue in GitHub if you need more assistance.
Make use of Edje.js and you should create a function and send the parameters when you call the function.
getHorarioFarmacia({pSede:'Sucursal Parrita'}, function (error, result){....
}
For more details, read the comments made by Luis Diego Pizarro here.
private static String XXX = "{call SP_XXX(?,?,?)}"
sql.call (XXX, [Sql.NUMERIC, Sql.NUMERIC,'SOME STRING'){
outPara1, outPara2 ->
log.info("${outPara1}, ${outPara2}")
}
I am able to call the stored procedure successful with the above code.
But, when I am using named parameters instead of '?' placeholder.
I am getting:
WARNING: Failed to execute: {call SP_XXX(:OUTP1, :OUTP2, :INP1)}
because: Invalid column type
What I changed is replaced the '?' with ":OUTP1", "OUTP2" and ":INP1".
And in the call statement, using the named parameters accordingly.
The code after change:
private static String XXX = "{call SP_XXX(:OUTP1, :OUTP2, :INP1)}"
sql.call (XXX, [OUTP1: Sql.NUMERIC, OUTP2: Sql.NUMERIC, INP1: 'SOME STRING']){
outPara1, outPara2 ->
log.info("${outPara1}, ${outPara2}")
}
What you are doing is passing a map to call() which I do not think we have an api for. Moreover, the placeholders for the SP has to be ?.
Either you can stick to your former approach or try using GString as below:
def inp1 = 'SOME STRING'
sql.call "{call SP_XXX(${Sql.NUMERIC}, ${Sql.NUMERIC}, $inp1)}", {
outPara1, outPara2 ->
log.info("${outPara1}, ${outPara2}")
}
I would prefer the former approach instead. :-)
In groovy tutorial: http://groovy.codehaus.org/Database+features
there is section about procedure. When I try this example:
The same example again but with a GString variation:
def first = 'Sam'
sql.call("{$Sql.VARCHAR = call FullName($first)}") { name ->
assert name == 'Sam Pullara'
}
I got exception:
Chyba: ORA-06550: line 1, column 13:
PLS-00222: no function with name 'FULLNAME' exists in this scope
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
java.sql.SQLException: ORA-06550: line 1, column 13:
PLS-00222: no function with name 'FULLNAME' exists in this scope
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
yes that is true what exception says because I got just procedure FULLNAME what I want to call not function. Is this tutorial still actual ?
In Oracle, a stored procedure cannot return a value and a function can return a value. This is why you get that error. You can verify using my testing stored procedure and groovy code...
CREATE OR REPLACE PROCEDURE test_procedure
( string_in IN OUT VARCHAR2 ) IS
BEGIN
string_in := 'hi ' || string_in ;
END;
import groovy.sql.Sql
Sql sql = Sql.newInstance("jdbc:oracle:thin:#hostname:1521:dbname", username","password","oracle.jdbc.driver.OracleDriver")
def first="Wade"
sql.call '{call test_procedure(?)}',
[Sql.inout(Sql.VARCHAR(first))],
{ test ->
println ">>" + test + "<<"; // >>hi Wade<<
}
import groovy.sql.Sql
import oracle.jdbc.driver.OracleTypes
Sql sql = Sql.newInstance("jdbc:oracle:thin:#hostname:1521:dbname", "username","password","oracle.jdbc.driver.OracleDriver")
dept_id = 50
sql.call('{? = call FullName(?)}', [Sql.VARCHAR, 'Sam']) { name->
println name
}