I have an Issue running a psql script.
this is the output :
File.SQL:155: ERROR: syntax error at or near ":"
LINE 10: date_temp_Ale INTEGER := :'param_date';
i have a file.sh that is calling the "File.sql" with and Input varible.
here is the line that callsthe sql script:
line in file.sh:
echo le numero des parametres est bien 7
psql -v PGPASSWORD=$MDP -h $IP_MACHINE -f $FIC_REQ_SQL -v param_date=20180101 -U $UTILISATEUR -d $NOM_BDD -p $PORT > $FIC_LOG_EXEC_TMP 2>&1
echo Done in $FIC_LOG_EXEC_TMP
here is the line in the psql script:
line in file.sql"
--- UT 48 PURGE DES TRACES
\set ON_ERROR_STOP on
BEGIN; -- DEBUT DE TRANSACTION
DO $$
DECLARE
num_tra_err_id RECORD;
num_trace_composant RECORD;
num_trace_fonctionnelle RECORD;
num_message_id RECORD;
num_metadonnees_id RECORD;
num_Process_id RECORD;
datediff integer;
date_temp_Ale INTEGER := :'param_date';
Max_days integer := 180;
--date_limite varchar := &1;
BEGIN
i also tried to use the command " --set " in the file.sh but it didn't work.
i found a slution:
the DO statement isolate the inner code from the outer code.
to pass the info we need to store it as psql variable as follow
select set_config('psql.param_date', :param_date, false);
BEGIN; -- DEBUT DE TRANSACTION
DO
$$
DECLARE
limit_date varchar = current_setting('psql.param_date');
Related
I have a PostgreSQL statement which raises notices. I wish to redirect this output into a bash array. I have tried the following:
declare -a MYARRAY
MYARRAY=( `psql -U $db_username -h $DATABASE_HOST $DATABASE_NAME -c \
"DO \\$\\$ DECLARE
mySite varchar;
myResult RECORD;
BEGIN
RAISE NOTICE 'current_site, folder, path';
FOR mySite IN SELECT name from public.app_info
LOOP
{Confidential Data here!}
LOOP
RAISE NOTICE '%,%,%', myResult.current_site, myResult.folder, myResult.path;
END LOOP;
END LOOP;
END\\$\\$"` )
echo "These are the files"
for i in ${MYARRAY[#]}; do
echo $i
done
When I run my script my notices from the query are printed to my window but they are not added into the array. I have also tried this with a variable instead of an array, with no luck.
Notices are printed into stderr so change
END\\$\\$"` ) to END\\$\\$" 2>&1` )
but array will contain also texts like NOTICE: and DO so you have to filter them out
#!/bin/sh
output=ANIL;
#
# Ask user for database inputs
#
echo -n "Enter Database Server Hostname: "
read dba_host
echo -n "Enter Database SID: "
read dba_sid
echo -n "Enter DBA User: "
read dba_usr
echo -n "Enter DBA password: "
read dba_pwd
echo -n "What daemon are we using: "
read daemon_str
#
# Loop to connect to database and exit if something is found
#
while :
do
output=`sqlplus $dba_usr/$dba_pwd#$dba_sid <<+ | grep '^-' | sed 's/-//'
set serveroutput on
DECLARE
command VARCHAR2(50);
return_name VARCHAR2(30);
value VARCHAR2(10000);
status INT;
system_time TIMESTAMP := SYSTIMESTAMP;
WHILE TRUE
BEGIN
status := DBMS_PIPE.RECEIVE_MESSAGE($daemon_str);
IF status = 0 THEN
DMS_PIPE.UNPACK_MESSAGE(command);
END IF;
IF command = "STOP" THEN
DBMS_OUTPUT.PUT_LINE('STOP was encountered') >> file.log;
DBMS_OUTPUT.PUT_LINE(system_time) >> file.log;
BREAK
ELSIF command = "SYSTEM" THEN
DBMS_PIPE.UNPACK_MESSAGE(return_name);
DBMS_PIPE.UNPACK_MESSAGE(value);
EXIT
$value
ELSIF command = "SQL"
DBMS_PIPE.UNPACK_MESSAGE(return_name);
DBMS_PIPE.UNPACK_MESSAGE(value);
EXECUTE IMMEDIATE value;
ELSE
nap(10)
EXCEPTION
WHEN OTHERS THEN
dbms_ouput.put_line('Unknown Input Error') >> file.log;
DBMS_OUTPUT.PUT_LINE(system_time) >> file.log;
DBMS_PIPE.PACK_MESSAGE('done');
DBMS_PIPE.PACK_MESSAGE(status);
status := DBMS_PIPE.SEND_MESSAGE(return_name,10);
END;
dbms_output.put_line(chr(10) || '-' || command);
END;
/
exit
+`
echo $output
done
I am trying to convert a c code block to what you see now a shell script block. I am just a beginner in this coding language and was wanting to know if anyone is seeing something I am not. To sum up what I am trying to accomplish is ask user for the oracle database they want to connect to then keep connection and receive things through pipe. Then the usual of unpacking, outputting errors and such. Then sending it back through same pipe. Any input on possible syntax or anything at all that could be causing this to constantly echo out nothing but blank lines from while loop.
I need to develop a shell script that updates some records on a oracle database, this programs read an input .txt file and then updates the record when some conditions are met, but for some reason this records were not updated, it seems that there's a problem with a variable that the plsql reads in order to update the records.
This is the shell script code
## #!/bin/sh
. /usr/local/bin/oracle.profile.prod
. /usr/local/bin/bscs.profile.prod
hostname=`uname -n`
basedato=BSCS1REP
if [[ $basedato = "BSCS2PROD" && $hostname = "comp35" ]];then
export Y/Shell
export Y/Sql
export Y/Log
export Y/Cfg
. Y.MM.txt
elif [ $basedato = "BSCS1REP" and $hostname = "comp44" ]; then
export X/Shell
export X/Sql
export X/Log
export X/Cfg
. X/.MM.txt
else
echo "ERROR, Servidor no valido para la ejecucion de este programa"
echo "Base de Datos = "$basedato
echo "Maquina = "$hostname
exit 1
fi
FECHA=$(date "+%Y%m%d_%H_%M_%S")
cat $RUTA_CFG/MSISDN.txt | while read elemento
do
set $elemento
elemento=$1
echo "El registro es $elemento "insertado""
sqlplus -S $USER/$PASS#$basedato #$RUTA_PLS/Num_Act.sql $elemento > $RUTA_LOG/test.txt
done
rm -f $RUTA_CFG/Act_num.ctl
echo "DONE"
As you can see this script reads an input data, is the following:
123456789
Just this simple string.
Now this is the invoked Pl/sql
ALTER SESSION SET OPTIMIZER_GOAL = CHOOSE;
ALTER SESSION SET NLS_LANGUAGE = AMERICAN;
ALTER SESSION SET NLS_TERRITORY = AMERICA;
SET serveroutput ON SIZE 1000000
SET term ON
WHENEVER SQLERROR CONTINUE
DECLARE
elemento constant varchar2(30) := '$1';
BEGIN
update directory_number dn
set dn.dn_status = 'a'
where dn.dn_num = ('$1')
and dn.dn_status in ('d','t','Z','f','r');
DBMS_OUTPUT.PUT_LINE (elemento);
END;
/
EXIT;
I added a log file to see what's going on, and it returned the following:
Session altered.
Session altered.
Session altered.
$1
PL/SQL procedure successfully completed.
The variable stands $1, and it should be the input data number.
Could be a sintax error ?, a variable declaration ?
When I put aside the variables and put directly the valor of the desire number in the plsql it updated the record with no problems.
Any help with be appreciated, thank so much for your time !
In your PL/SQL code try replacing $1 with &1.
See this link for an example and description.
I have a problem with executing a psql-query in a bash script.
Below is my code.
run_sql(){
sql_sel="$1;";#sql select
table=$2;#table name
for i in "${!GP_SERVER_NAMES[#]}"
do
logmsg "Executing [$sql_sel] on "${GP_SERVER_NAMES[$i]}": " $loglvl;
result_host[$i]=`${PSQL_HOST[$i]}${sql_sel}`;
#result_host[$i]=cleanresult "`$(${PSQL_HOST[$i]} "$tx_fix $sql_sel" 2>&1`");
if [[ `checkresult "${result_host[$i]}"` != 'true' ]]; then
logmsg "Error occured during sql select: Result for "${GP_SERVER_NAMES[$i]}" '${table}': ${result_host[$i]};" '1' '1';
raise_alarm "${GP_SYNC_SQL_ERR}" "${i}" "${table}" "${result_host}";
fi
logmsg "Result for" ${GP_SERVER_NAMES[$i]} " '${table}': ${result_host[$i]}";
done
final_result='true';
for i in "${!result_host[#]}"
do
if [[ `checkresult "${result_host[$i]}"` = 'true' ]]; then
final_result='false';
I am trying to executing the query on many different servers, with the following command
result_host[$i]=${PSQL_HOST[$i]}${sql_sel};
The above variables have the following meaning:
1. result_host[$i] : is an array that holds the i-th result of the sql query.
2. PSQL_HOST[$i] : is the command line psql-statement, including the IP address which is of the form
psql -t -q -h -U password -d database -c
3. $sql_sel : is the sql_statement
When I run the script, I get the following output.
scriptname.sh: line 168: SELECT: command not found
ERROR: syntax error at end of input
LINE 1: SELECT
^
Why is that? Any help, comments or suggestions would be appreciated.
I'm trying to create a FUNCTION in my Postgres database from a Bash script. Unfortunately, I cannot get it to work. This is my script:
#!/bin/bash
# Save Postgres command to $POSTGRES_CMD
read -d '' POSTGRES_CMD <<"EOF"
CREATE OR REPLACE FUNCTION truncate_tables(username IN VARCHAR) RETURNS void AS $$
DECLARE
statements CURSOR FOR
SELECT tablename FROM pg_tables
WHERE tableowner = username AND schemaname = 'public';
BEGIN
FOR stmt IN statements LOOP
EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ';';
END LOOP;
END;
$$
LANGUAGE plpgsql;
EOF
sudo su - postgres -c "psql -d postgres -U postgres -c \"${POSTGRES_CMD}\""
When I run the script, I get the following error:
ERROR: Syntax error at »20541«
LINE 1: ...N truncate_tables(username IN VARCHAR) RETURNS void AS 20541
So it seems like something is wrong with the $$? How can I create a FUNCTION like in my script in Postgres from a Bash script? Do I have to mask anything?
Edit:
The final, working script (also added create language if it's not registered yet):
#!/bin/bash
sudo su - postgres -c "psql -d postgres -U postgres" << 'EOF'
CREATE LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION truncate_tables(username IN VARCHAR) RETURNS void AS $$
DECLARE
statements CURSOR FOR
SELECT tablename FROM pg_tables
WHERE tableowner = 'username' AND schemaname = 'public';
BEGIN
FOR stmt IN statements LOOP
EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ';';
END LOOP;
END;
$$
LANGUAGE plpgsql;
The $$ is replaced by the process id you should escape the $$ thing like this \$\$ or even \\$\\$ as it is escaped two times
Use <<'EOF' to stop bash interpolating the here document.
addition:
You can avoid passing everything through "-c" by using:
sudo su - postgres -c "psql -d postgres -U postgres" <<'EOF'
...
EOF
as stdin should be preserved through sudo and su
if anyone is looking for a version where env variables are passed (DB_USERNAME, DB_SCHEMA) here is:
psql -U dev -d clinical_trial -h db -v ON_ERROR_STOP=1 << EOF
CREATE OR REPLACE FUNCTION truncate_tables() RETURNS void AS \$\$
DECLARE
statements CURSOR FOR
SELECT tablename FROM pg_tables
WHERE tableowner = '$DB_USERNAME' AND schemaname = '$DB_SCHEMA' AND tablename not like 'flyway%';
BEGIN
FOR stmt IN statements LOOP
EXECUTE 'TRUNCATE TABLE $DB_SCHEMA.' || quote_ident(stmt.tablename) || ';';
END LOOP;
END;
\$\$
LANGUAGE plpgsql;
EOF