I am new in oracle db...
I need to create a database link by passing link name and connection string as variable.
DECLARE DBLINK_NAME varchar(100) :='newdblink';
Connection varchar(250) := '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=host.name.com)(Port=1521))(CONNECT_DATA=(SID=host)))';
BEGIN
EXECUTE IMMEDIATE 'CREATE DATABASE LINK' ||DBLINK_NAME||
'CONNECT TO SCHEMA_NAME IDENTIFIED BY password USING '||Connection;
END;
Can any one tell me what wrong in passing this variable value in execute statement?
I am doing using TOAD and oracle 11g.
You have missed the spaces around the database link name, so your command ends up as:
CREATE DATABASE LINKnewdblinkCONNECT TO ...
which will generate an ORA-01501: CREATE DATABASE failed error. You need to include a space after LINK and before CONNECT.
Your connect string also needs to be enclosed in single quotes, so you need to concatenate those as well, and they need to be escaped:
DECLARE
DBLINK_NAME varchar(100) :='newdblink';
Connection varchar(250) := '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=host.name.com)(Port=1521))(CONNECT_DATA=(SID=host)))';
BEGIN
EXECUTE IMMEDIATE 'CREATE DATABASE LINK ' || DBLINK_NAME
|| ' CONNECT TO SCHEMA_NAME IDENTIFIED BY password USING '''
|| Connection || '''';
END;
/
PL/SQL procedure successfully completed.
It's helpful to use dbms_output to display exactly what the execute immediate will try to run. You can often spot mistakes quickly - the missing spaces would have been pretty obvious - and can copy-and-patse the generated statement to run it as plain SQL, which can sometimes make other issues more obvious.
I'm not sure what the benefit of using PL/SQL, variables and dynamic SQL is here. You can just do a simple SQL statement using those values. Perhaps you intend to turn this into a procedure. But creating a link at run-time would be unusual.
Related
i want to create in mysql an event schedule every day that check
if the current date is greater than a date stored in the database table and then call some store procedures.
Reading my WRONG mysql code you will understand that i want to do:
delimiter $
set global event_scheduler = on$
create event if not exists `end_qualifications`
on schedule
every day
do
begin
if curdate() >= (select `end_date` from `round` where `nome` =
"qualifications")
then
/* call myprocedure(params); */
end if;
end $
delimiter ;
I found here If-statement in the MySQL stored procedure for selecting data something similar, but there is not way my code work as i want.
I'm a beginner with mysql so it's possible that what i want to do can't be done.
Anyone knows how to make my code work?
I'm using MySQL client version: 5.7.25
EDITED: this is the error i get when i try to run the query
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MariaDB server version for the right
syntax to use near 'do
begin
if curdate() >= (select `end_date` from `round` where `nome` =
"q' at line 5
I don't know if it matters, but the database is empty for now.
I'm the DBA administrator, and i want to create the following procedure:
CREATE OR REPLACE PROCEDURE PRUEBAS.TOMAPRIVILEGIOS(USUARIOS VARCHAR) AS
BEGIN
EXECUTE IMMEDIATE 'REVOKE CONNECT TO '||USUARIOS||'';
END TOMAPRIVILEGIOS;
/
But appear one error.
BEGIN PRUEBAS.TOMAPRIVILEGIOS('PRUEBAS'); END;
Informe de error -
ORA-00990: falta el privilegio o no es válido
ORA-06512: en "PRUEBAS.TOMAPRIVILEGIOS", línea 3
ORA-06512: en línea 1
00990. 00000 - "missing or invalid privilege"
*Cause:
*Action:
If you want to do DDL in a procedure, you need to use dynamic SQL. EXECUTE IMMEDIATE is probably the easiest way to do so. Something like
CREATE OR REPLACE PROCEDURE( p_username IN VARCHAR2 )
AS
l_sql VARCHAR2(1000);
BEGIN
l_sql := 'GRANT CONNECT TO ' || dbms_assert.schema_name( p_username );
EXECUTE IMMEDIATE l_sql;
END;
Generally, it's easiest to build up the string you want to execute in a local variable and then pass that to EXECUTE IMMEDIATE. That makes debugging much easier when you can just log the string you've built rather than trying to figure out what the syntax error is. When you're using dynamic SQL, you're opening yourself up to SQL injection attacks so you want to verify your inputs with either the dbms_assert package or through some custom means.
As an aside, you probably want to create custom roles rather than relying on something like CONNECT. Oracle removed a bunch of permissions from CONNECT in 10.2 so that it now only allows database connections but in prior versions it was much more powerful than the name implies. You generally ought not use the CONNECT and RESOURCE roles, you're generally better off creating your own roles with the exact privileges you want.
I am trying to create tables dynamically in a SQL Server database.
Like this with input from a textbox:
ALTER PROCEDURE [dbo].[opretNyEsyn]
#Navn NVARCHAR(100)
AS
BEGIN
DECLARE #SQLString NVARCHAR(MAX)
SET #SQLString = 'create table ' + QUOTENAME(#Navn) +
'([EsynNummer][int]Identity(1,1),
[Dato][datetime])'
END
But nothing happens when I run the method from the form, the table isn't created, and I get no errors.
What am I missing?
Notice. This is just a test table. It isn't supposed to look like this in the end.
Thanks in advance
You are just creating the statement, but in order to create the tables, you need to Execute the statement using the EXEC statement of sp_executesql SP. Add an execute statement to your Procedure. Like this
ALTER PROCEDURE [dbo].[opretNyEsyn]
#Navn nvarchar(100)
as
Begin
declare #SQLString nvarchar(max)
set #SQLString = 'create table ' + QUOTENAME(#Navn)+
'([EsynNummer][int]Identity(1,1),
[Dato][datetime])'
exec(#SQLString)-- Execute the Statement
End
Go
You need to execute dynamic SQL:
ALTER PROCEDURE [dbo].[opretNyEsyn]
#Navn SYSNAME
as
Begin
declare #SQLString nvarchar(max);
set #SQLString = 'create table ' + QUOTENAME(#Navn)+
'([EsynNummer][int]Identity(1,1),
[Dato][datetime])';
EXECUTE (#SQLString);
End;
Anyway I recommend to read The Curse and Blessings of Dynamic SQL and Packaging Permissions in Stored Procedures:
CREATE TABLE #tbl
The desire here is to create a table of which the name is determined at run-time.
If we just look at the arguments against using dynamic SQL in stored procedures, few of them are really applicable here. If a stored procedure has a static CREATE TABLE in it, the user who runs the procedure must have permissions to create tables, so dynamic SQL will not change anything. Plan caching obviously has nothing to do with it. Etc.
Nevertheless: Why? Why would you want to do this? If you are creating tables on the fly in your application, you have missed some fundamentals about database design. In a relational database, the set of tables and columns are supposed to be constant. They may change with the installation of new versions, but not during run-time.
Say I have a sql file which is executed from command prompt (SQL Plus), which is working fine.
sqlplus dbusername/dbpassword#DBInstance #sqlfilename.sql
Now I need to pass a parameter to this sql spool file and according to the value of parameter I should be able to determine the functionality in the sql file. In the below sql code, I need to store the value that I am passing as parameter and in the variable parameter_Value
SET SERVEROUTPUT ON
SET DEFINE OFF
SPOOL "Test.log"
var parameter_Value VARCHAR2(20);
BEGIN
IF(parameter_Value='A')
THEN
--do something
ELSE
--do something
END IF;
END;
/
SPOOL OFF;
SET DEFINE ON
SET SERVEROUTPUT OFF
Can anyone please help how to perform this task?
Thanks in advance!
Your usage of the word spoolfile is not correct. sqlfilename.sql is the sql file or sqlplus file. The output file Test.log is the spool file.
you call
sqlplus dbusername/dbpassword#DBInstance #sqlfilename.sql A
to call the following file
SPOOL "Test.log"
DEFINE MY_VALUE=&1
SET SERVEROUTPUT ON
var parameter_Value VARCHAR2(20);
EXEC :parameter_Value:='&MY_VALUE'
SET DEFINE OFF
BEGIN
IF(:parameter_Value='A')
THEN
--do something
ELSE
--do something
END IF;
END;
/
SET DEFINE ON
SET SERVEROUTPUT OFF
SPOOL OFF;
the substitution of the & variables is a simple text substitution. It can be turned off by executing SET DEFINE OFF. The substituion raises information messages by sqlplus that can be turned off by executing SET VERIFY OFF
you should start with the SPOOL command, you won't see errors thrown by commands executed before you start spooling into the logfile. This can make debugging tedious. Also you should execute all commands before SPOOL OFF
the parameters in the command line are referend by their position number. I prefer assigning them to a named variable and use the named variable later. This is not necessary. You can use the positional parameter later, too, instead of using a named parameter. But using named parameter makes it easier to change the file if the position of a parameter changes. Also it can document the purpose of the parameter if you choose an appropriate name. I didn't in this example.
You cannot disable the special property of the & character with SET DEFINE OFF before the parameter substitution. You have to postpone it until you have done all your substitutions. Otherwise the substitution will not work.
a bind variable is definded with the VAR ... statement in sqlplus. In an SQL text it must be referenced with a preceding colon (:).
EXEC statement is an abbreviation for BEGIN statement; END
be aware that the --do something is in a PL/SQL block. So it must be replaced by PL/SQL statements and not by SQL statements or SQL*Plus statements.
So it cannot be replaced by a CREATE TABLE ... statement (this is SQL but not PL/SQL) and it cannot be replaced by a SPOOL OFF statement, which is SQL*Plus but not PL/SQL.
I have been asked to create an SP which creates temporary table and insert some records.
I am preparing some sample code for the same as mentioned below but the output is not displayed.
create or replace procedure Test
is
stmt varchar2(1000);
stmt2 varchar2(1000);
begin
stmt := 'create global temporary table temp_1(id number(10))';
execute immediate stmt;
insert into temp_1(id) values (10);
execute immediate 'Select * from temp_1';
execute immediate 'Drop table temp_1';
commit;
end;
When i am executing the SP by (Exec Test) desired O/P is not displayed.
I am expecting O/P of "Select * from temp_1" to be displayed. But it is not happening. Please suggest where i am doing wrong.
But i am interesting in knowing why ( execute immediate 'Select * from temp_1';) do not yield any result
For two reasons. Firstly because as #a_horse_with_no_name said PL/SQL won't display the result of a query. But more importantly here, perhaps, the query is never actually executed. This behaviour is stated in the documentation:
If dynamic_sql_statement is a SELECT statement, and you omit both into_clause and bulk_collect_into_clause, then *execute_immediate_statement( never executes.
You would have to execute immediate into a variable, or more likely a collection if your real scenario has more than one row, and then process that data - iterating over the collection in the bulk case.
There is not really a reliable way to display anything from PL/SQL; you can use dbms_output but that's more suited for debugging than real output, and you usually have no guarantee that the client will be configured to show whatever you put into its buffer.
This is all rather academic since creating and dropping a GTT on the fly is not a good idea and there are better ways to accomplish whatever it is you're trying to do.
The block you showed shouldn't actually run at all; as you're creating temp_1 dynamically, the static SQL insert into temp_1 will error as that table does not yet exist when the block is compiled. The insert would have to be dynamic too. Any dynamic SQL is a bit of a warning sign you're maybe doing something wrong, though it is sometimes necessary; having to do everything dynamically suggests the whole approach needs a rethink, as does creating objects at runtime.