Altering Stored Procedures in ASE Sybase 15.7 - sybase-ase15

I am new to ASE Sybase 15.7 but do have some background in other RDBMS systems. So i assumed there would be an equivalent of CREATE OR REPLACE for Stored procedures in ASE Sybase 15.7.
But I dont seem to see any way to do this. Most people i have asked suggest dropping and creating with the newer version of the stored procedure but that gives me a challenge of managing the permissions on the stored procedure which are different across environments depending on the users in each.
So My ask is below:
Suppose I have a stored procedure as so:
ENV1
CREATE Procedure test (
as
begin
SELECT getdate()
end
grant execute on test to group1
go
grant execute on test to group2
go
ENV2 has :
CREATE Procedure test (
as
begin
SELECT getdate()
end
grant execute on test to group1
go
grant execute on test to group2
go
grant execute on test to group3
go
I want to update this stored proc to give me 2 dates instead of 1 so new proc should be
ENV1:
CREATE Procedure test (
as
begin
SELECT getdate(), getdate()
end
grant execute on test to group1
go
grant execute on test to group2
go
ENV2:
CREATE Procedure test (
as
begin
SELECT getdate(), getdate()
end
grant execute on test to group1
go
grant execute on test to group2
go
grant execute on test to group3
go
Above is a very simplistic example ofcourse. Is there a way to deploy the changes to just modify the stored procedure body preserving the permissions?
CREATE or REPLACE and ALTER PROCEDURE dont seem to work and dropping and creating the stored procedure would mean additional logic for each environment to figure out the permissions to be granted.
Is there a way to do this kind of deployment in an optimum way considering we have 20 plus different user environments?
Thanks!

While ASE does support create or replace, this is only available with ASE 16.x (ie, you'd need to upgrade to ASE 16.x).
Assuming you're looking to build some sort of scripted solution, I'd recommend taking a look at the ddlgen utility to assist with extracting the current permissions for a stored proc.
One (very simple) example of using ddlgen to pull the DDL for a stored proc:
$ ddlgen -SmyASE -Umylogin -Pmypassword -TP -Nsybsystemprocs.dbo.sp_help -Osp_help.ddl.out
$ cat sp_help.ddl.out
-- Sybase Adaptive Server Enterprise DDL Generator Utility/1 ...snip...
...snip...
use sybsystemprocs
go
...snip...
create procedure sp_help
...snip...
Grant Execute on dbo.sp_help to public Granted by dbo
go
sp_procxmode 'sp_help', anymode
go
From here you could grep out the desired grant, revoke and/or sp_procxmode lines, to be (re)executed once you've dropped/created the replacement stored proc.
If you don't have access to ddlgen (I know it's included in the ASE installation software but don't recall if it's provided in the SDK/client software installation) you have a few alternatives:
have the DBA run the ddlgen commands for you and provide you with the results (yeah, I'm sure the DBA will love that idea)
get ddlgen installed on your 'client' machine (eg, install the ASE installation package; or copy over just the needed files from an ASE installation - easier said than done, and would be a PITA when it comes to upgrading the software)
run sp_helprotect <proc_name> (and sp_procxmode <proc_name>) and parse the output for the desired grant, revoke and/or sp_procxmode commands
And one alternative on the 'run-and-parse sp_helprotect/sp_procxmode output' ... look at the source code for these procs and roll your own SQL code to extract the desired data in a format that's easier for you process to handle.

Related

How do I access the AST (abstract syntax tree) for a PL/SQL stored procedure?

When Oracle compiles a stored procedure, it stores the AST for the procedure in DIANA format.
how can I access this AST?
are there built-in tools for processing this AST?
There is an undocumented package DUMPDIANA that is meant to dump the Diana in a human-readable format.
The file $ORACLE_HOME\rdbms\admin\dumpdian.sql says "Documentation is available in /vobs/plsql/notes/dumpdiana.txt". I cannot find that file, and without it we can only guess at the meaning of some parameters. Basic usage of DUMPDIANA is as follows:
SQL> show user
USER is "SYS"
SQL> #?\rdbms\admin\dumpdian
Library created.
Package created.
Package body created.
create or replace procedure hello_world
2 as
3 begin
4 dbms_output.put_line('hello world');
5* end;
Procedure created.
SQL> set serveroutput on
SQL> execute sys.DUMPDIANA.dump('HELLO_WORLD');
user: SYS
PL/SQL procedure successfully completed.
At this point a pair of files should have been created in the folder
$ORACLE_BASE/diag/rdbms/orcl12c/orcl12c/trace. The two files seem to follow the naming convention:
orcl12c_ora_{PROCESS}.trc
orcl12c_ora_{PROCESS.trm
Where the trc file is a human readable version of the corresponding trm file, and {PROCESS} is the operating system process ID. To find this use the following query from the same session:
select p.spid from v$session s,v$process p
where s.paddr = p.addr
and s.sid = sys_context('USERENV','SID');
For example if the session ID was 8861 then from a bash shell you can view the results using:
vim $ORACLE_BASE/diag/rdbms/orcl12c/orcl12c/trace/orcl12c_ora_8861.trc
The result is interesting... if not particularly intuitive! For example here is a snippet of the file produced. Note the HELLO_WORLD string literal.
PD1(2):D_COMP_U [
L_SRCPOS : row 1 col 1
A_CONTEX :
PD2(2): D_CONTEX [
L_SRCPOS : row 1 col 1
AS_LIST : < >
]
A_UNIT_B :
PD3(2): D_S_BODY [
L_SRCPOS : row 1 col 1
A_D_ :
PD4(2): DI_PROC [
L_SRCPOS : row 1 col 11
L_SYMREP : HELLO_WORLD,
S_SPEC : PD5^(2),
S_BODY : PD8^(2),
A couple of notes. I've run this as SYS, which as we know is not a good practice, this is no reason I know of why you shouldn't grant privileges on DUMPDIANA to a normal user. All the procedures you dump go into the same file - if you delete that file, it stops working, and you'll need to start a new session. If it stops working, starting a new session sometimes seems to fix the problem.
Here is an excellent tutorial on DIANA and IDL in the PDF How to unwrap PL/SQL by Pete Finnigan, principal consultant at Siemens at the time of the writting, specializing in researching and securing Oracle databases.
Among other very interesting things you will learn that:
DIANA is written down as IDL (Interface Definition Language).
The 4 tables the IDL is stored in (IDL_CHAR$, IDL_SB4$, IDL_UB1$ and IDL_UB2$)
Wrapper PL/SQL is simply DIANA written down as IDL.
Dumpdiana is not installed by default, you need to ensure DIANA, PIDL, and DIUTIL PL/SQL packages are installed as well and you need to run it as SYS.
How to dump the DIANA tree and understand it.
How to reconstruct the PL/SQL source from DIANA.
How to write a PL/SQL un-wrapper.
Limitations of a PL/SQL API based un-wrapper.
Limitations of the PL/SQL API itself.
How to enumerate DIANA nodes and attributes.
A proof of concept un-wrapper.
You can find his website here. There is so much content there. You will find awesome papers about Oracle security and also a lot of useful security tools developed not only by him but other authors as well.
Best of all, you can get in touch with him if after the reading you still have questions.

Test Scripts for PL/SQL Stored Procs

With TSQL I'm used to putting some repeatable tests in for my stored procs. Typically this may include putting the db in a particular state, runnings the sproc, validating the state and rolling back. And contrived example might something like this"
BEGIN TRAN
--input for test case
DECLARE #TestName VARCHAR(10) = 'bob'
--insert test row
INSERT INTO tbl (data) values (#TestName)
--display initial state of target row
SELECT * FROM tbl WHERE data = #TestName
--do some useful test
EXEC MyProc
--display the final state of the target row
SELECT * FROM tbl WHERE data = #TestName
--put the db back where it started
ROLLBACK TRAN
Now I'm working with Oracle and PL/SQL and I'm trying to use a some similar pattern to test my work and not finding it obvious to me quite how to do that. I believe there are a few different ways I might accomplish it but haven't gotten anything to actually work. Ideally I would have a single script in which I could run multiple test cases and inspect the result.
I am trying to work in PL/SQL Developer at this point and understand that might have some differences from how it might work in Oracle SQL Developer or elsewhere.
In Oracle, using tools like SQL*Plus and GUI tools like SQL Developer, you have many options :
To execute the statements and procedures in a single session in an order, i.e. using procedural method of PL/SQL, write an anonymous plsql block and execute it as a script.
Most of the GUI based tools have an option like Execute as script or Test Window to execute your scripts individually or embedded in an anonymous block.
Using DBMS_SCHEDULER also you could achieve the same task.
As you are interested in PL/SQL Developer tool product of Allround Automations, you could simply use the test window to test individual objects.
I have documented few useful features of the PL/SQL Developer tool in my blog, please read http://lalitkumarb.wordpress.com/2014/08/14/plsql-developer-settings/

Is there a way to make Visual Studio 2010 database projects use DROP and CREATE instead of ALTER for DML

When building a deploy script for a Visual Studio 2010 SQL database project, is there any way to instruct the process to use DROP and CREATE for stored procedures and other DML instead of always ALTERing them?
As an example, if I change a stored procedure, the deploy script will generate something like this...
ALTER PROCEDURE MyProc
AS
SELECT yadda...
I want the deploy script to create something like this instead
IF EXISTS MyProc
DROP MyProc
CREATE PROCEDURE MyProc
AS
SELECT yadda....
It would make version controlled upgrade scripts a bit easier to manage, and deployed changes would perform better. Also if this is not possible, a way to at least issue a RECOMPILE with the ALTER would help some.
This question asks something that seems similar, but I do not want this behavior for tables, just DML.
I'm not familiar enough with database projects to give an answer about whether it's possible to do a DROP and CREATE. However, in general I find that CREATE and ALTER is better than DROP and CREATE.
By CREATE and ALTER I mean something like:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = 'MyProc'
AND ROUTINE_TYPE = 'PROCEDURE')
BEGIN;
-- CREATE PROC has to be the first statement in a batch so
-- cannot appear within a conditional block. To get around
-- this, make the statement a string and use sp_ExecuteSql.
DECLARE #DummyCreateText NVARCHAR(100);
SET #DummyCreateText = 'CREATE PROC dbo.MyProc AS SELECT 0;';
EXEC sp_ExecuteSql #DummyCreateText;
END;
GO
ALTER PROCEDURE dbo.MyProc
AS
SELECT yadda...
The advantage of CREATE and ALTER over DROP and CREATE is that the stored proc is only created once. Once created it is never dropped so there is no chance of permissions getting dropped and not recreated.
In a perfect world the permissions on the stored proc would be applied via a database role so it would be easy to reapply them after dropping and recreating the stored proc. In reality, however, I often find that after a few years other applications may start using the same stored proc or well-meaning DBAs may apply new permissions for some reason. So
I've found that DROP and CREATE tend to cause applications to break after a few years (and it's always worse when it's someone else's application that you know nothing about). CREATE and ALTER avoids these problems.
By the way, the dummy create statement, "CREATE PROC dbo.MyProc AS SELECT 0" , works with any stored procedure. If the real stored procedure is going to have parameters or return a recordset with multiple columns that can all be specified in the ALTER PROC statement. The CREATE PROC statement just has to create the simplest stored procedure possible. (of course, the name of the stored proc in the CREATE PROC statement will need to change to match the name of your stored proc)

Can GRANT be used inside an Oracle Store Procedure?

When trying to place a GRANT statement in an Oracle 11 stored procedure, it reports that GRANT is an unexpected symbol. Does GRANT need to be prefaced by something, or does Oracle simply disallow running GRANTS inside SPs?
It's a bad idea to use DDL (like GRANT) inside stored procedures.
You will have to use dynamic SQL (EXECUTE IMMEDIATE) to do this, but, honestly, I don't see why would you want to do this inside a stored proc.
Here's a PL/SQL stored procedure that grants object privileges (SELECT, UPDATE, etc.) on all tables owned by the current user to another user, e.g. - "appuser".
CREATE OR REPLACE PROCEDURE grant_privs
IS
CURSOR ut_cur IS SELECT table_name from user_tables;
ut_rec ut_cur%rowtype;
BEGIN
FOR ut_rec IN ut_cur
LOOP
EXECUTE IMMEDIATE 'GRANT ALL ON ' || ut_rec.table_name || ' TO appuser';
END LOOP;
END;
/
It was executed automatically after deploying database changes for a web application. The current user owns the database tables. After deploying any database changes, the stored procedure was executed to ensure that "appuser" could run SQL statements on all of the tables. The web application connected as "appuser", which had only limited system privileges, for security reasons.
This is both a solution to the problem and a solid use case for the solution.

how will you take only stored procedure backup in oracle 10g?

how will you take only stored procedure backup in oracle 10g?
ammoQ's answer is correct.
To take it a bit further, if you want just the stored procs without the table structure, you will need to connect to the database and use SQL (i.e. with sqlplus or something). Then, using a list of the stored procs you are interested in, call the dbms_metadata function. You can use sqlplus to do something like this:
SELECT dbms_metadata.get_ddl('PROCEDURE','PROC1') FROM dual;
which will give you the source of procedure PROC1.
Also there is a view called USER_SOURCE, which you can use something like this:
select * from user_source where type in ('PROCEDURE', 'PACKAGE', 'PACKAGE_BODY', 'FUNCTION', 'TRIGGER');
which gives you the source for everything owned by the user you are logged in as.
Tools like TOAD offer a feature to export the source code of stored procedures, functions, packages, triggers etc.
If you don't mind exporting table structure (without content) as well,
exp user/password file=emptybackup.dmp owner=myschema rows=n
should do the trick.
If you're not taking care of configuration management, i.e. not keeping your stored procedures in a proper source control application (e.g. CVS, Subversion, MSS) you're simply not doing the right thing. Even a one-man team should use a version control system, for any non-trivial work.
Read up on Revision control

Resources