Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

Although this first section is already covered by Rob Verschoor (www.sypron.nl) i would like to repeat a part of his description because it makes ASE life a lot easier.

ASE 15.x supports 'scalar-valued SQL UDFs', which are UDFs returning a single value only. This is to distinguish from 'table-valued SQL UDFs', which return a table: ASE does not support such UDFs at this point.

SQL UDFs are located in the database where they are created, but they can be called from other databases.

A SQL UDF must be prefixed with the owner name of the function. This follows the same convention as used by SQL UDFs in MS SQL Server.

An important practical aspect of SQL UDFs is that you can name them with an "sp_" prefix, and place them in the sybsystemprocs database so that the UDF will be accessible from anywhere in the ASE server. Without this trick, you'd have to explicitly specify the database where the UDF is located.

Note! You cannot use this trick with UDFs in MS SQL Server!

Example 1:

We want to know in which directory a certain datadevice for further use in a stored procedure. We can retrieve this from sysdevices but we are only interested in the directory not the full path. By making use of a UDF we can achief this. This function can be applied to every query that returns a full path.

The basic query:

1> select phyname from master..sysdevices where vdevno = 1

2> go

phyname

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

C:\Sybase\data\sysprocs.dat

(1 row affected)

Now with a the getDir function:

1> declare @test varchar(100)

2> declare @output varchar(100)

3> select @test = phyname from master..sysdevices where vdevno = 1

4> select @output = dbo.getDir(@test)

5> print @output

6> go

(1 row affected)

(1 row affected)

C:\Sybase\data\

1>

Code: getDir function


-- remove the function if exists
if(object_id("getDir")) != 0
begin
   drop function getDir
end
go
------------------------------------------------------------
-- File: action_getDir.sql  
-- Name: getDir
-- Desc: Get the directory from a path without the file
-- Auth: H. Splinter
-- Date: 08-02-2014
------------------------------------------------------------
-- Change History
------------------------------------------------------------
-- PR   Date     Author         Description
------------------------------------------------------------
-- 001  09-02-2014   H. Splinter    Remove getDir if exists
------------------------------------------------------------
-- create the function
create function getDir(@path varchar(1000))
returns varchar(1000)
as
begin
  -- declarations
  declare @dir varchar(100)
  -- extract the directory
  select @dir = reverse(substring(reverse(@path),(charindex("\",(reverse(@path)))),((char_length(@path)+1)-(charindex("\",(reverse(@path)))))))
  -- return the value
  return @dir
end

Nested User Defined Function

Although undocumented a UDF can call another UDF.

In the next example we determine the directory separator based on the Operating System(OS) where the ASE server is installed. This can be used as a "dynamic" variable in per example the build of a dump location string.

1> select dbo.dirSeperator(dbo.os())

2> go

\

(1 row affected)

1>

Code: os function


-- remove the function if exists
if(object_id("os")) != 0
begin
   drop function os
end
go
------------------------------------------------------------
-- File: action_os.sql
-- Name: os
-- Desc: Returns the operating system ASE is on as an INT.
--       (AIX (0) | HP-UX (1) | Linux (2) | Sun (3) |  VMS (4) | Windows (5))
-- Auth: H. Splinter
-- Date: 26-11-2012
------------------------------------------------------------
-- Change History
------------------------------------------------------------
-- PR   Date     Author         Description
------------------------------------------------------------
-- 001  28-12-2012   H. Splinter  Remove function if exists
-- 002  20-02-2014   H. Splinter  Remove clutter
------------------------------------------------------------
-- create the function
create function os
returns int
as
begin
  -- declarations
  declare @os int
  -- get the OS and set the return variable
  if (select patindex('%AIX%', @@version))<> 0
  set @os = 0
  else
  if (select patindex('%HP-UX%', @@version))<> 0
  set @os = 1
  else
  if (select patindex('%Linux%', @@version))<> 0
  set @os = 2
  else
  if (select patindex('%SUN%', @@version))<> 0
  set @os = 3
  else
  if (select patindex('%VMS%', @@version))<> 0
  set @os = 4
  else
  if (select patindex('%Windows%', @@version))<> 0
  set @os = 5
  return @os -- return the corresponding OS number.
end

Code: dirSeperator function


-- remove the function if exists
if(object_id("dirSeperator")) != 0
begin
   drop function dirSeperator
end
go
------------------------------------------------------------
-- File: action_dirSeperator
-- Name: dirSeperator
-- Desc: Returns the right directory seperator for tje operating system ASE is on as an char.
--       (AIX (/) | HP-UX (/) | Linux (/) | Sun (/) |  VMS (/) | Windows (\))
-- Auth: H. Splinter
-- Date: 26-11-2012
------------------------------------------------------------
-- Change History
------------------------------------------------------------
-- PR   Date     Author         Description
------------------------------------------------------------
--
------------------------------------------------------------
-- create the function
create function dirSeperator(@os int)
returns char(1)
as
begin
  -- declarations
  declare @seperator char(1)
  -- set the return variable
  if (select @os)= 5
     set @seperator = "\"
  else
     set @seperator = "/"
  return @seperator -- return the corresponding seperator
end


Although the above examples are simple. They can be very powerfull in terms of repeating the same job over and over again. They are small, quick and handy! I am building every small job into a function when possible and, as shown above, get code I can reuse on basicly every OS/Platform with ASE.


Aknowledgements:

User Defined Functions - Rob Verschoor www.sypron.nl

Labels in this area