Quantcast
Channel: SCN: Message List
Viewing all articles
Browse latest Browse all 8581

Re: How can i Switch database inside procedure in Sybase ASE

$
0
0

You can combine a few basic ASE features that'll allow you to execute a vast majority of ASE commands in a any database.

 

Basic features:

 

1 - Most (but not all) commands can be submitted to ASE via a exec(<string_arg>) call, where '<string_arg>' is a string containing the command(s) you wish to execute. For variable commands the SQL developer can populate a local @variable with the desired command(s) and then issue exec(@variable).

 

2 - Any stored procs created in the sybsystemprocs database with a prefix of 'sp_' can be executed from within any database in the dataserver.  You're likely familiar with quite a few of these procs that come with ASE, eg, sp_who, sp_help*, sp_configure, etc.  There's nothing to keep the DBA from adding his/her own sp_* procs to the sybsystemprocs database so that they can be executed from within any database.

 

3 - When executing a stored proc, if you preface the proc name with '<dbname>..', said proc will be executed from within the <dbname> database ... just as if you had issued 'use <dbname>' followed by 'exec <procname>...'.  In the following example, the user is sitting in the master database but viewing the contents of the testdb database:

 

==================

use master

go

-- run the sp_helpdb proc in the testdb database

exec testdb..sp_help

go

... list of all objects in the testdb database

==================

 

------------

 

Using all of these features it's possible to create a sp_* proc that accepts a long string; a string that contains your desired command(s).

 

The sp_* proc can then be run in any database by simply prefacing the sp_* call with the name of the database.

 

For example:

 

==================

-- give my proc dataserver-wide access by creating

-- in the sybsystemprocs database with a prefix of 'sp_'

 

use sybsystemprocs

go

 

-- I tend to add an extra '_' to distinguish my custom procs from

-- those provided by SAP/Sybase

 

if object_id('sp__execute_command') is not NULL

     drop proc sp__execute_command

go

 

create proc sp__execute_command

@command varchar(16384)

as

exec(@command)

go

 

-- grant permissions as you see fit

 

grant execute on sp__execute_command to public

go

 

-- while sitting in the master database ...

 

use master

go

 

-- create a new table in the testdb database, and

-- grant 'select' to the public group

 

exec testdb..sp__execute_command 'create table t1 (a int, b int) grant select on t1 to public'

go

 

-- let's go see if it worked ...

 

use testdb

go

 

sp_help t1

go

 

Name Owner Object_type Object_stats         Create_date

---- ----- ----------- -------------------- -------------------

t1   dbo   user table  keep first text page May 29 2015  9:04PM

... snip ...

 

sp_helprotect t1

go

 

grantor grantee type  action object column predicate grantable

------- ------- ----- ------ ------ ------ --------- ---------

dbo     public  Grant Select t1     All    NULL      FALSE

==================

 

------------

 

This is a very basic example. Keep in mind ...

 

- the caller is responsible for submitting a) syntactically correct commands and b) knowing which commands can in fact be submitted via the exec() construct

 

- you'll find that most exec() calls that deal with DDL commands usually cannot be run inside a transaction sooo, do you add some checks to verify you're not in a txn before making the exec() call, or leave this up to the caller to address as s/he sees fit?

 

- you'll need to decide who has permissions to execute the sp_* proc; alternatively add logic in the proc to verify the caller's credentials in the database where the proc is executed

 

- I'm not 100% sure the exec() can actually handle a 16K string ... so you'll need to test that out if you plan on submitting some really long commands


Viewing all articles
Browse latest Browse all 8581

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>