I'm new to pl/sql and my question is: is it possible to "compile" a script in sql plus or sql developer and give the file to other person in order to allow other to execute the code but not allowing them to read the code?
It sounds like you are talking about the Oracle wrap utility (a separate command-line application that is part of your Oracle client install and not a part of SQL Developer) or the dbms_ddl.wrap function which you could invoke from SQL Developer. These create obfuscated statements that will create a stored procedure (or package or function) that behaves normally but where the text in the data dictionary is not human readable. The wrap utility doesn't provide perfect security-- there are unwrapping tools and presentations on the internet that would let an attacker unwrap the code you hand them. And you can often figure out what the unwrapped code is really doing by looking at other data dictionary views (v$sql will show the unwrapped SQL statements that are executed for example) or by tracing a session.
It depends also of definition of the word give. You can store PL/SQL code in the database. Give users right to execute it, to see the source code of the package header, but not to see the source of package body. But of course DBAs can read it, They can also trace it (even if it is wrapped).
Also note that PL/SQL packages are wrapped in a different way than PL/SQL procedures. As of 11g packages are wrapped using simple one-to-one byte substitution. While for PL/SQL procedures, there is stored obfuscated bytecode of DIANA virtual machine. AFAIK there is no accessible unwrap for PL/SQL procedures, it is much harder to reverse engineer.
Related
I am not sure in case of Stored Procedures, if Postgresql treats static sql any differently from a query submitted as a quoted string.
When I create a stored procedure in PostgreSQL using static sql, there seems to be no validation of the table names and table columns or column types but when I run the procedure I get the listing of the problems if any.
open ref_cursor_variable for
select usr_name from usres_master;
-- This is a typing mistake. The table name should be users_master. But the stored procedure is created and the error is thrown only when I run the procedure.
When I run the procedure I (naturally) get some error like :
table usres_master - invalid table name
The above is a trivial version. The real procedures we use at work combine several tables and run to at least a few hundred lines. In PostgresQL stored procedure, is there no advantage to using static sql over dynamic sql i.e. something like open ref_cursor_variable for EXECUTE select_query_string_variable.
The static SQL should be preferred almost time - dynamic SQL should be used only when it is necessary
from performance reasons (dynamic SQL doesn't reuse execution plans). One shot plan can be better some times (and necessary).
can reduce lot of code
In other cases uses static SQL every time. Benefits:
readability
reuse of execution plans
it is safe against SQL injection by default
static check is available
The source of a function is just a string to Postgres. The main reason for this is the fact that Postgres (unlike other DBMS) supports many, even installable languages for functions and procedures. As the Postgres core can't possibly know the syntax of all languages, it can not validate the "inner" part of a function. To my knowledge the "language API" does not contain any "validate" method (in theory this would probably be possible though).
If you want to statically validate your PL/pgSQL functions (and procedures since Postgres 11) you could use e.g. https://github.com/okbob/plpgsql_check/
Is it possible to use or add parameters on a simple query without the need of creating stored procedures or function? Are Bind Variables possible without creating a stored procedures?
where are you running the code from? If your running from a language like Java / VB you would use a stored procedure or prepared statement.
If using from Sql *Plus terminal or other Sql UI
SQL> variable deptno number
SQL> exec :deptno := 10
SQL> select * from
emp where deptno = :deptno;
From a high level language like Java or VB use stored procedures, following is from the article you linked to so not sure why you are asking this?
In fact, the answer to this is actually quite simple. When you put
together an SQL statement using Java, or VB, or whatever, you usually
use an API for accessing the database; ADO in the case of VB, JDBC in
the case of Java. All of these APIs have built-in support for bind
variables, and it's just a case of using this support rather than just
concatenating a string yourself and submitting it to the database.
For example, Java has PreparedStatement, which allows the use of bind
variables, and Statement, which uses the string concatenation
approach. If you use the method that supports bind variables, the API
itself passes the bind variable value to Oracle at runtime, and you
just submit your SQL statement as normal. There's no need to
separately pass the bind variable value to Oracle, and actually no
additional work on your part. Support for bind variables isn't just
limited to Oracle - it's common to other RDBMS platforms such as
Microsoft SQL Server, so there's no excuse for not using them just
because they might be an Oracle-only feature.
Not sure why you are asking as this information is there on the site http://www.akadia.com/services/ora_bind_variables.html
Well, assuming you will perform queries using an external programming language, prepared statements will make the job.
See http://en.wikipedia.org/wiki/Prepared_statement
I defined a role and grant it with only connect to database and execute a specific stored procedure. Users have this role can see the body of procedure when execute this query;
select * from ALL_SOURCE where NAME = 'procedureName';
Procedure takes a VARCHAR2 parameter and uses it with a select query. Is that a security issue? Should i hide it somehow or escape the parameter?
Generally, it would only be a security issue if your procedure was subject to SQL injection. The fact that you talk about escaping the parameter implies that you may be doing dynamic SQL and may be vulnerable to SQL injection attacks. If that's the case, you need to fix the procedure, not hide the source.
If your stored procedure is implementing some business logic that you consider proprietary, you could potentially wrap the code so that it is obfuscated in the data dictionary. If you do that, however, make absolutely sure that you your source code in source control because there is no way to unwrap code once you've wrapped it (strictly speaking, there are various techniques that an attacker can use to recover most of the wrapped source if they really wanted to, but it's reasonably secure).
Let's say I've got a large script and want to cut it into pieces and then load the pieces from a main script file.
The question is how to load and execute an external script using plain SQL in Oracle DBMS or PL/SQL from another script file?
For SQL*plus, you can use:
#filename.sql
or
##filename.sql
Please realize that # is a SQL*plus command - not a SQL or PL/SQL command. SO you cannot use this from inside a PL/SQL stored procedure - it would not make much sense either, as essential context like current working direcory is absent in that case.
Form inside a stored procedure, you could in principle load external code using dynamic sql, but a better way to break up a stored procedure is to break it into several smaller stored procedures. If you like you can group those togehter in a package (see http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10472/packages.htm#CIHIJECJ)
I have a situation where I have an Oracle procedure that is being called from at least 3 or 4 different places. I need to be able to be able to call custom-code depending on some data. The custom-code is customer-specific - so, customer A might want to do A-B-C where customer B might want to do 6-7-8 and customer C doesn't need to do anything extra. When customers D...Z come along, I don't want to have to modify my existing procedure.
I'd like to be able to enter the customer-specific procedure into a table. In this existing procedure, check that database table if a custom-code procedure exists and if so, execute it. Each of the customer-code procedures would have the same parameters.
For instance:
My application (3+ places) calls this "delete" procedure
In this delete procedure, look up the name of a child-procedure to call (if one exists at all)
If one exists, execute that delete procedure (passing the parameters in)
I know I can do this with building a string that contains the call to the stored procedure. But, I'd like to know if Oracle 10g has anything built in for doing this kind of thing?
Do each of your customers have their own database? If so the best option would be to use conditional compilation. This has the advantage of not requiring dynamic SQL. Have the main program always call the custom procedure, and use CC flags to vary the code it contains.
Otherwise, Oracle does have a Rule Engine but it is not really intended for our use.
The final solution that we went with was to store the name of a procedure in a database table. We then build the SQL call and use an EXECUTE statement.
Agree with APC's answer and just to expand on it, in this white paper if you look for "Component based installation" it describes a similar problem solved by using conditional compilation.
Your solution seems reasonable given the requirements, so I voted it up.
Another option would be to loop through the results from your table look-up and put calls to the procedures inside a big case statement. It would be more code, but it would have the advantage of making the dependency chain visible so you could more easily catch missing permissions and invalid procedures.