Having error while declaring binding variable in pl/sql - oracle

Hi I am getting the error, need advise. The code is:
VARIABLE v_bind1 VARCHAR2(10); --declare bind variable
exec : v_bind1 := 'RebellionRider'; --execute it
SET SERVEROUTPUT ON;
BEGIN
dbms_output.put_line(v_bind1);
END;
It prints the below output when m trying to declare the variable:
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
NVARCHAR2 (n) | CLOB | NCLOB | BLOB | BFILE
REFCURSOR | BINARY_FLOAT | BINARY_DOUBLE ] ]
and when tried to print it, it shows below error:
SP2-0552: Bind variable "V_BIND1" not declared.

You need to have the : right next to the bind name:
VARIABLE v_bind1 VARCHAR2(10); --declare bind variable
exec :v_bind1 := 'RebellionRider'; --execute it
and then reference it as :v_bind1.
For reference:
You reference bind variables in PL/SQL by typing a colon (:) followed
immediately by the name of the variable. For example

Assuming this is SQL*Plus and not PL/SQL Developer as the error you posted is a SQL*Plus error, it's because of the trailing comment:
Fails:
SQL> VARIABLE v_bind1 VARCHAR2(10); --declare bind variable
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
NVARCHAR2 (n) | CLOB | NCLOB | BLOB | BFILE
REFCURSOR | BINARY_FLOAT | BINARY_DOUBLE ] ]
Succeeds:
SQL> VARIABLE v_bind1 VARCHAR2(10);
SQL>
The SQL terminator character (by default it's ; but don't forget it's configurable) must appear at the end of the line, otherwise SQL*Plus won't recognise it. But SQL*Plus commands like variable don't need a SQL terminator and don't have any comment syntax anyway, so the whole line is rejected as invalid.
The next issue you had was that v_bind1 and :v_bind1 are two different things. This fails because v_bind1 is an undeclared PL/SQL local variable (it would have needed to be declared within the block):
begin
dbms_output.put_line(v_bind1);
end;
/
What you needed was the bind variable you just declared named :v_bind1:
begin
dbms_output.put_line(:v_bind1);
end;
/
As v_ and : both indicate a variable, I'd suggest you don't need the first one.

Related

Concat variable with a string in location parameter in a create statement?

In Greenplum, I need to create an external table with a dynamic location parameter. For an example:
CREATE READABLE TABLE_A(
date_inic date,
func_name varchar,
q_session bigint
)
LOCATION(:location)
FORMAT 'TEXT' (DELIMITER '|');
But in :location parameter I need to concat it with a fixed string. I tried:
LOCATION (:location || '123')
But I get a syntax error, otherwise in select statement it works perfectly. I'm inserting :location value like: " 'gphdfs://teste:1010/tmp' "
Can anyone help me?
You are missing a few things in your table definition. You forgot "external" and "table".
CREATE READABLE EXTERNAL TABLE table_a
(
date_inic date,
func_name varchar,
q_session bigint
)
LOCATION(:location)
FORMAT 'TEXT' (DELIMITER '|');
Note: gphdfs has been deprecated and you should use PXF or gpfdist instead.
Next, you just need to use double quotes around the location value.
[gpadmin#mdw ~]$ psql -f example.sql -v location="'gpfdist://teste:1010/tmp'"
CREATE EXTERNAL TABLE
[gpadmin#mdw ~]$ psql
psql (9.4.24)
Type "help" for help.
gpadmin=# \d+ table_a
External table "public.table_a"
Column | Type | Modifiers | Storage | Stats target | Description
-----------+-------------------+-----------+----------+--------------+-------------
date_inic | date | | plain | |
func_name | character varying | | extended | |
q_session | bigint | | plain | |
Type: readable
Encoding: UTF8
Format type: text
Format options: delimiter '|' null '\N' escape '\'
External options: {}
External location: gpfdist://teste:1010/tmp
Execute on: all segments
And from bash, you can just concat the strings together too.
loc="gpfdist://teste"
port="1010"
dir="tmp"
location="'""$loc"":""$port""/""$dir""'"
psql -f example.sql -v location="$location"

Using SAS to insert rows containing nulls and blanks into database

I have a db2 table DBTable with columns A, B, C (all of type varchar) which is linked to a library lib in SAS.
I use SAS to generate a dataset ValuesForA with one column whose content I want to write into the column A of DBTable with the additional requirement that the the column for B is filled with ' ' (blank) and the column for C with (null). So the DBTable should look something like this:
| A | B | C |
======================
| 'x' | ' ' | (null) |
| 'y' | ' ' | (null) |
| 'z' | ' ' | (null) |
I cannot find a way how to acchieve this as SAS as it treats blanks as null.
The simple approach specifying B as " " just fills this column with (null). I also tried to use the nullchar=no option and not specifying a value for C:
proc sql;
insert into lib.DBTable
(nullchar=no, A, B)
select
A, " " as B
from ValuesForA;
quit;
however the column C is then also filled with blanks
| A | B | C |
===================
| 'x' | ' ' | ' ' |
| 'y' | ' ' | ' ' |
| 'z' | ' ' | ' ' |
Try this:
proc sql;
insert into lib.DBTable
select
A, " " as B, null as C
from ValuesForA;
quit;
This gave me the results you requested using a DB2 temp table with three VARCHAR columns.
I posted the same question on communities.sas.com.
In the end, I used a solution proposed by s_lassen (you may check out his other one).
I give my own description of his solution here:
It seems that inserting blanks and nulls is not possible over the linked libraies. We can, however, write a SAS-program that produces an sql-statement which we can execute on the database server itself using pass-through sql.
This is all done by this little script:
/* *** Create a temporary document with the name "tempsas" *** */
Filename tempsas temp;
/* *** Loop throuhg ValuesForA and write into tempsas. *** */
/* (The resulting tempsas is basically an SQL insert statement. All observations are written in one big values statement) */
Data _null_;
file tempsas;
set ValuesForA end=done;
if _N_=1 then put
'rsubmit;' /
'proc sql;' /
' Connect to DB2(<connect options>);' /
' execute by DB2(' /
' insert into DBTable(A, B, C)' /
' values'
;
put
" ('" a +(-1) "', ' ', null)" #; /* "a" is an observation ValuesForA.a
"+(-1)" removes the trailing blank set by the put statement
"#" writes the next put statement in the same line */
if done then put
/
' );' /
'quit;' /
'endrsubmit;'
;
else put ',';
run;
/* *** Run the code in tempsas *** */
%include tempsas;
It creates a file "tempsas" in which it writes and executes the following code:
rsubmit;
proc sql;
Connect to DB2(<connect options>);
execute by DB2(
insert into DBTable(A, B, C)
values
('x', ' ', null),
('y', ' ', null),
('z', ' ', null)
);
quit;
endrsubmit;
I guess this solution is only feasible if there are not too many values to be inserted to the database.

Oracle plsql - want to generate and use single id for current run

I am creating a log table something like below
Run_id | Log_id | Procedure_name | Log_text
Log_id is a running sequence. Run_id is a group id for all the log texts generated by a procedure in a given run.
How to achieve this?
A procedure which wants to insert record into above log table will call a LOG_PROCEDURE. So I am planning to put all the logic in this LOG_PROCEDURE.
Example:
Run_id | Log_id | Procedure_name | Log_text
1 | 1 | p1 | table updated
1 | 2 | p1 | table inserted
1 | 3 | p1 | record deleted
You can create a trigger, which will set the Log_id for you after each insert in the log table. Add a parameter to the procedure, which will pass the current value of the sequence for Run_id and each time you log in the procedure, you'll use this value. At the end of the procedure you'll just increment the variable so the next procedure will have the correct value.

How to access parameters inside a Netezza stored procedure?

This is my stored procedure:
nzsql -u user -pw pass -c "CREATE OR REPLACE PROCEDURE INSERT_LOGIC(varchar(50),varchar(20),varchar(40)) RETURNS BOOL LANGUAGE NZPLSQL AS BEGIN_PROC
DECLARE
t1 ALIAS FOR $1;
t2 ALIAS FOR $2;
t3 ALIAS FOR $3;
BEGIN
INSERT INTO ABC..XYZ
(select '$t1','$t2','$t3' from ABC..PQR limit 10);
END;
END_PROC;"
The ALIAS FOR is the only way I found on the internet to do this but I get the following error:
NOTICE: plpgsql: ERROR during compile of INSERT_LOGIC near line 3
ERROR: syntax error, unexpected ERROR, expecting VARIABLE or WORD at or near "t1Stuff"
How do I access the three "varchar variables" that I pass to the stored procedure inside the same?
Here is an example similar to your requirement and its working. I am using two tables 'tab1' and 'tab2' with following description:
$ nzsql -d test -c "\d tab1"
Table "TAB1"
Attribute | Type | Modifier | Default Value
-----------+---------------+----------+---------------
COL1 | INTEGER | |
COL2 | CHARACTER(10) | |
COL3 | INTEGER | |
Distributed on hash: "COL1"
$ nzsql -d test -c "\d tab2"
Table "TAB2"
Attribute | Type | Modifier | Default Value
-----------+---------------+----------+---------------
C1 | INTEGER | |
C2 | CHARACTER(10) | |
C3 | INTEGER | |
Distributed on hash: "C1"
Following is the stored procedure code that I used:
CREATE OR REPLACE PROCEDURE INSERT_LOGIC(varchar(50),varchar(20),varchar(40))
RETURNS BOOL
LANGUAGE NZPLSQL
AS
BEGIN_PROC
DECLARE
num_args int4;
sql char(100);
t1 ALIAS FOR $1;
t2 ALIAS FOR $2;
t3 ALIAS FOR $3;
BEGIN
num_args := PROC_ARGUMENT_TYPES.count;
RAISE NOTICE 'Number of arguments: %', num_args;
sql := 'INSERT INTO tab2 SELECT ' || t1 || ',' || t2 || ',' || t3 || ' FROM tab1 LIMIT 10 ';
RAISE NOTICE 'SQL Statement: %', sql;
EXECUTE IMMEDIATE sql;
END;
END_PROC;
Hope this will help!
You're attempting to reference variables by putting a $ in front of the name, which is not valid.
Look at the example in the docs.
DECLARE
logtxt ALIAS FOR $1;
curtime timestamp;
BEGIN
curtime := 'now()';
INSERT INTO logtable VALUES (logtxt, curtime);
RETURN curtime;
END
You should try
INSERT INTO ABC..XYZ
(select t1, t2, t3 from ABC..PQR limit 10);
Though it's possible that the column values won't resolve when used this way. If not, build a dynamic statement and execute it instead.
declare sql varchar;
sql := 'insert into abc..xyz select ' || t1 || ',' || t2 || ',' || t3 || ' from abc..pqr limit 10;'
execute immediate sql;
If you're passing values, not column names, as parameters:
declare sql varchar;
sql := 'insert into abc..xyz select ''' || t1 || ''',''' || t2 || ''',''' || t3 || ''' from abc..pqr limit 10;'
execute immediate sql;

NVARCHAR2 constants in package specification

I try to add a constant in package specification with nvarchar2 datatype but after compilation it stores in database something like ???. For example I try to add a constant for armenian word մեկ
x constant nvarchar2(3) default 'մեկ';
Can anyone suggest a solution to this problem or it is impossible to do so?
I have tested you example on two different databases with different NLS_CHARACTERSET configurations.
Configurations (recived by query -
select *
from v$nls_parameters
where parameter in ('NLS_NCHAR_CHARACTERSET','NLS_CHARACTERSET','NLS_LANGUAGE')
):
First:
+----+------------------------+----------+
| id | PARAMETER | VALUE |
+----+------------------------+----------+
| 1 | NLS_LANGUAGE | AMERICAN |
| 2 | NLS_CHARACTERSET | AL32UTF8 |
| 3 | NLS_NCHAR_CHARACTERSET | AL16UTF16|
+----+------------------------+----------+
Second:
+----+------------------------+-------------+
| id | PARAMETER | VALUE |
+----+------------------------+-------------+
| 1 | NLS_LANGUAGE | RUSSIAN |
| 2 | NLS_CHARACTERSET | CL8MSWIN1251|
| 3 | NLS_NCHAR_CHARACTERSET | AL16UTF16 |
+----+------------------------+-------------+
And the result is following, on DB with charset AL32UTF8 variable displays correctly, on charset CL8MSWIN1251 with questions '???'.
I haven't change charsests on databases to validate my suggestion. So I suggest you change NLS_CHARACTERSET to AL32UTF8 it should help.
My package for tests:
create or replace package question27577711 is
x constant nvarchar2(3) default 'մեկ';
function get_constant_x return nvarchar2;
end question27577711;
create or replace package body question27577711 is
function get_constant_x
return nvarchar2
is
begin
return x;
end get_constant_x;
end question27577711;
select question27577711.get_constant_x from dual

Resources