Dynamic Procedure BigQuery - google-bigquery

Does Bigquery support dynamic procedure calls? I am looking to generate a procedure name as string based on variables and call the string.
EXECUTE IMMEDIATE returns this error clearly it doesn't support CALL. Is there any other way?
SQL created by EXECUTE IMMEDIATE contains unsupported statement type: CallStatement.
Thank you.

I make this answer for visibility, the approach you can use is as follow (as mention in the comments by mikhail):
CREATE OR REPLACE PROCEDURE `project-id.dataset`.maker(option INT64)
BEGIN
IF option=1 THEN
CALL `project-id.dataset`.create_user(); #call to procedure
ELSEIF option=2 THEN
CALL `project-id.dataset`.create_customer(); #call to procedure
ELSE
SELECT "END"; #default
END IF;
END
to use
CALL `project-id.dataset`.maker(2)
As stated in the comments, execute immediate do not support at the moment the usage of call.
I also found a feature request about supporting using call with execute immediate on google issue tracker you can leave a comment to support the feature request.

Related

Catching OUT parameter value of a bigquery Procedure from composer

I am calling a bigquery procedure using BigQueryInsertJob operator using "declare out_var String; call bq_sp("input params", out_var)". This is getting called properly and executing the stored procedure properly also. But what I need to do along with that, is to print the value of out_var to the composer log, to catch the value of out_var, so that I can do some more things depending on the value of that variable. Could you please help me, how can I catch the value of the OUT parameter value from the cloud composer. Thank you.
I have a stored procedure with input and output parameters. and calling that from composer.
This is working absolutely fine.
I am expecting to fetch the OUT parameter value in the cloud composer job

Adding a / as an end delimeter on Liquibase Oracle SQL statement

While using Liquibase feature, I extended liquibase.sqlgenerator.core.CreateIndexGenerator class to convert this command
create index indexI on tableT(columnC)
into something like this:
declare
index_already_exists exception;
pragma exception_init(index_already_exists, -955);
--
begin
execute immediate 'create index indexI on tableT(columnC)';
exception
when index_already_exists then
dbms_output.put_line('Warning: Index indexI already exists');
end;
to make it idempotent and create some new validations.
It is working perfectly when using mvn liquibase:update. But, when generating the SQL using mvn liquibase:updateSQL a final / (slash) is missing.
Looking at Liquibase sourcecode I found out that the class LoggingExecutor used to have what I need on method outputStatement
} else if (database instanceof OracleDatabase) {
output.write(StreamUtil.getLineSeparator());
output.write("/");
I tried to add a final / (slash) after the end; if, but it becomes like this :
end;
/;
which is invalid PLSQL code
Is there another way to add a final / on the SQL generated code, or set the / as an end delimeter ?
Instead of extending CreateIndexGenerator you could instead override CreateIndexChange.generateStatements() to return a RawSqlStatement with your SQL. That allows you to better set the end delimiter and may work better with the LoggingExecutor.
I'm using liquibase 3.4.2 and the end delimiter / is recognized automatically. When I mean automatically you don't have to use the property endDelimiter in the declaration of the changeset. It turns out that in some older versions of liquibase a bug was introduced during the parsing.
Please check http://www.liquibase.org/2015/06/liquibase-3-4-0-released.html
and you will see that they fix the issue https://liquibase.jira.com/browse/CORE-2227. This issue was affecting the version 3.3.2.
So I suggest you to use a newer version or specify correctly the endDelimiter property in the declaration of the changeset.
http://www.liquibase.org/documentation/changes/sql.html

Way to access a REST Service via a SQL Server stored procedure?

We are looking for a way to call a REST service from a SQL Server 2008 & newer stored procedure. We do not need to get any information from this service. We just need to force the call to run in the middle of a stored procedure.
I have found some 3rd party options or CLR; but I refuse to think there isn't an easier way since we just need to fire a call and don't need anything in return.
Hopefully someone can shed some light. Thanks!
You could make a SQL Agent job to run a PowerShell script, then run the job via msdb.dbo.sp_start_job. That way you wouldn't need any external scripts or utilites, nor any SQL-CLR.
Your job step would be something like:
$request = [System.Net.WebRequest]::Create('http://stackoverflow.com/')
$result = $request.GetResponse()
I can think at least of 2 ways of doing that:
1) Probably prefered way:
Make a C# dll and call its function from the store procedure example:
How to call C# function in stored procedure
2) Call the rest service with the help of CURL utility.
DECLARE #PassedVariable VARCHAR(100)
DECLARE #CMDSQL VARCHAR(1000)
SET #PassedVariable = 'SqlAuthority.com'
SET #CMDSQL = 'c:findword.bat' + #PassedVariable
EXEC master..xp_CMDShell #CMDSQL
have the call to the ws inside the bat file

calling function or procedure within same package

Can I call a function or procedure by using package name, if they are defined in the same package?
May be this will be helpful for you.
http://docs.oracle.com/cd/B10501_01/appdev.920/a96590/adg10pck.htm
Yes You can call it using procedure name, for your help see the link
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:7452431376537

How do you retrieve the return value of a DB2 SQL sproc using Perl DBI?

I need to retrieve the value returned by a DB2 sproc that I have written. The sproc returns the number of rows in a table and is used by the calling process to decide whether or not to update other data.
I have looked at several similar questions on SO but they refer to the use of out parameters instead of using the sproc's return value, for example:
Perl Dbi and stored procedures
I am using a standard DBI connection to the database with both RaiseError and PrintError enabled.
$sql_stmt = "call MY_TABLE_SPACE.MY_SPROC('2011-10-31')";
$sth = $dbh->prepare($sql_stmt)
or die "Unable to prepare SQL '$sql_stmt': $rps_met_dbh->errstr";
$rsp = 0;
$rsp = $sth->execute();
unless($rsp) {
print(STDERR "Unable to execute sproc: $rps_met_dbh->errstr\n");
}
print(STDERR "$?\n");
I have tried looking at $h->err for both the statement handle and the db handle.
I would really prefer communicating the number of rows via a return code rather than using SQLSTATE mechanism if I can.
Edit:
I have finished up using a dedicated out parameter to communicate the number of rows updated as follows:
$sql_stmt = "call MY_TABLE_SPACE.MY_SPROC('2011-10-31')";
$sth = $dbh->prepare($sql_stmt)
or die "Unable to prepare SQL '$sql_stmt': $rps_met_dbh->errstr";
$sth = $dbh->bind_param_inout(1, $rows_updated, 128)
or die "Unable to prepare SQL '$sql_stmt': $rps_met_dbh->errstr";
$rows_updated = 0;
$rsp = 0;
$rsp = $sth->execute();
unless($rsp) {
print(STDERR "Unable to execute sproc: $rps_met_dbh->errstr\n");
}
print(STDERR "$rows_updated\n");
Edit 2:
And now thinking about this further I have realised that I should apply the PragProg principle of "Tell. Don't Ask." That is, I shouldn't call the sproc. then have it give me back a number before I decide whether or not to call the anopther sproc, i.e. "Ask".
I should just call the first sproc. and have it decide whether it should call the other sproc or not, i.e. "Tell" and let it decide.
What is wrong with using an output parameter in your procedure. I've not got a working DB2 lying around right now or I'd provide an example but when I was using it I'm sure you can define output parameters in procedures and bind them with bind_param_inout. I cannot remember if a DB2 procedure can return a value (like a function) but if it can them using "? = call MY_TABLE_SPACE.MY_SPROC('2011-10-31')" would allow you to bind the output return value. If this doesn't work you could use a DB2 function which definitely can return a value. However, at the end of the day the way you get data out of a procedure/function is to bind output parameters - that is just the way it is.
I've no idea what you mean by "using SQLSTATE". I've also no idea what you mean by looking at $h->err as that is only set if the procedure fails or you cannot call the procedure (SQL error etc).