Sybase - Get names of procs calling a given proc - stored-procedures

I am looking for a functionality in reverse to sp_depends. sp_depends gives names of objects that the current object is using.
I want to get info in a reverse manner i.e. what all objects(procs in my case) calls the given proc ?
Note
I am using Sybase 12.5

I hope it will help you:
declare #Proc varchar(30)
select #Proc='ProcName'
select sod.name
from sysobjects so
join sysdepends sd on sd.id = so.id
join sysobjects sod on sod.id = sd.depid
where so.name = #Proc
and sod.type = 'P'

Try this query, I fixed the query of the previous answer, It gets the stored procedure(s) than call(s) the given stored procedure:
declare #Proc varchar(30)
select #Proc='procedure name'
select so.name
from sysobjects so
join sysdepends sd on sd.id = so.id
join sysobjects sod on sod.id = sd.depid
where sod.name = #Proc
and sod.type = 'P';

Related

Join procedures only once on Firebird

I'm trying to left join two stored procedures in a Firebird query.
In my example data the first returns 70 records, the second just 1 record.
select
--...
from MYSP1('ABC', 123) s1
left join MYSP2('DEF', 456) s2
on s1.FIELDA = s2.FIELDA
and s1.FIELDB = s2.FIELDB
The problem is performances: it takes 10 seconds, while each procedure takes less than 1 second. I suspect that procedures are run multiple times instead of just once. It would make sense to execute them just once, because I pass fixed parameters to them.
Is there a way to oblige Firebird to simply execute once each procedure and then join their results?
Since it seems there is no way, I solved this issue running this query inside a new stored procedure, where I cache all results from MYSP2 into a global temporary table and make the join between MYSP1 and the temporary table.
This is temporary table definition:
create global temporary table MY_TEMP_TABLE
(
FIELDA varchar(3) not null,
FIELDB smallint not null,
FIELDC varchar(10) not null
);
This is stored procedure body:
--cache MYSP2 results
delete from MY_TEMP_TABLE;
insert into MY_TEMP_TABLE
select *
from MYSP2('DEF', 456)
;
--join data
for
select
--...
from MYSP1('ABC', 123) s1
left join MY_TEMP_TABLE s2
on s1.FIELDA = s2.FIELDA
and s1.FIELDB = s2.FIELDB
into
--...
do
suspend;
But if there is another solution without temporary tables it would be great!
Maybe this can help:
with MYSP2W as (MYSP2('DEF', 456))
select
--...
from MYSP1('ABC', 123) s1
left join MYSP2W s2
on s1.FIELDA = s2.FIELDA
and s1.FIELDB = s2.FIELDB

How to get the table name from a column in a join query with SQL Server and FIREDAC?

I looking for get metadata on a TFDQuery (FireDAC).
I have this query:
SELECT *
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.Code = t2.code
I would like to know the column information (table name, the real column name in the table, ....)
I find this post : How to get the table name from a field in a join query with MSSQL? (mysql_field_table equivalent) but I have not the same structure on FireDac.
As RBA already mentioned you have to enable ExtendedMetaData in the connection first. When done you can get the field column description via query.GetFieldColumn(field) and access the table and column name with its ActualOriginTabName and ActualOriginColName properties.
column := query.GetFieldColumn(field);
orgTableName := column.ActualOriginTabName;
orgColumnName := column.ActualOriginColName;

How to get return rowcount from stored proceedure - SQL Server 2012

I am writing a stored procedure in SQL Server 2012 and facing problem while reading the number of rows that the stored procedure will return after matching all the conditions and join criteria.
My stored procedure is:
SELECT DISTINCT
COUNT(crs.CourseId) OVER() AS Recordcounts,
crs.CourseId,
crs.CourseName,
crs.CourseDescription,
(SELECT CourseGroupName FROM CourseGroup cgrp
WHERE cgrp.CourseGroupId = crs.CourseGroupId) AS Category
FROM
Courses crs
INNER JOIN
CourseRequests creq ON crs.CourseId = creq.CourseId
WHERE
crs.Coursename <> ''''
It is returning 16 as "Recordcounts" for one of condition, but in actual, the result is 3 rows only.
Can anybody help me with this?
Thanks
Below screenshot will give more clear idea about problem for one of condition:
Try this:
;with cte as(
SELECT distinct
crs.CourseId,
crs.CourseName,
crs.CourseDescription,
(SELECT CourseGroupName FROM CourseGroup cgrp
WHERE cgrp.CourseGroupId = crs.CourseGroupId) AS Category
FROM
Courses crs
INNER JOIN
CourseRequests creq ON crs.CourseId = creq.CourseId
WHERE
crs.Coursename <> '''')
Select *, (select COUNT(CourseId) from cte) AS Recordcounts
from cte

Most Efficient Version of PLSQL Stored Procedure

I am writing a PL/SQL stored procedure which will be called from within a .NET application.
My stored procedure must return
the count of values in a table of part revisions, based on an input part number,
the name of the lowest revision level currently captured in this table for the input part number
the name of the revision level for a particular unit in the database associated with this part number and an input unit ID.
The unit's revision level name is captured within a separate table with no direct relationship to the part revision table.
Relevant data structure:
Table Part has columns:
Part_ID int PK
Part_Number varchar2(30)
Table Part_Revisions:
Revision_ID int PK
Revision_Name varchar2(100)
Revision_Level int
Part_ID int FK
Table Unit:
Unit_ID int PK
Part_ID int FK
Table Unit_Revision:
Unit_ID int PK
Revision_Name varchar2(100)
With that said, what is the most efficient way for me to query these three data elements into a ref cursor for output? I am considering the following option 1:
OPEN cursor o_Return_Cursor FOR
SELECT (SELECT COUNT (*)
FROM Part_Revisions pr
inner join PART pa on pa.part_id = pr.part_id
WHERE PA.PART_NO = :1 )
AS "Cnt_PN_Revisions",
(select pr1.Revision_Name from Part_Revisions pr1
inner join PART pa1 on pa1.part_id = pr1.part_id
WHERE PA.PART_NO = :1 and pr1.Revision_Level = 0)
AS "Input_Revison_Level",
(select ur.Revision_Name from Unit_Revision ur
WHERE ur.Unit_ID = :2) as "Unit_Revision"
FROM DUAL;
However, Toad's Explain Plan returns Cost:2 Cardinality: 1, which I suspect is due to me using DUAL in my main query. Comparing that to option 2:
select pr.Revision_Name, (select count(*)
from Part_Revisions pr1
where pr1.part_id = pr.part_id) as "Count",
(select ur.Revision_Name
from Unit_Revision ur
where ur.Unit_ID = :2) as "Unit_Revision"
from Part_Revisions pr
inner join PART pa on pa.part_id = pr.part_id
WHERE PA.PART_NO = :1 and pr.Revision_Level = 0
Essentially I don't really know how to compare the results from my execution plans, to chose the best design. I have also considered a version of option 1, where instead of joining twice to the Part table, I select the Part_ID into a local variable, and simply query the Part_Revisions table based on that value. However, this is not something I can use the Explain Plan to analyze.
Your description and select statements look different... I based the procedure on the SQL statements.
PROCEDURE the_proc
(
part_no_in IN NUMBER
, revision_level_in IN NUMBER
, unit_id_in IN NUMBER
, part_rev_count_out OUT NUMBER
, part_rev_name_out OUT VARCHAR2
, unit_rev_name_out OUT VARCHAR2
)
AS
BEGIN
SELECT COUNT(*)
INTO part_rev_count_out
FROM part pa
WHERE pa.part_no = part_no_in
AND EXISTS
(
SELECT 1
FROM part_revisions pr
WHERE pa.part_id = pr.part_id
);
SELECT pr1.revision_name
INTO part_rev_name_out
FROM part_revisions pr1
WHERE pr1.revision_level = revision_level_in
AND EXISTS
(
SELECT 1
FROM part pa1
WHERE pa1.part_id = pr1.part_id
AND pa.part_no = part_no_in
);
SELECT ur.revision_name
INTO unit_rev_name_out
FROM unit_revision ur
WHERE ur.unit_id = unit_id_in;
END the_proc;
It looks like you are obtaining scalar values. Rather than return a cursor, just return the values using clean sql statements. I have done this numerous times from .net, it works fine.
Procedure get_part_info(p_partnum in part.part_number%type
, ret_count out integer
, ret_revision_level out part_revisions.revision_level%type
, ret_revision_name out part_revisions.revision_name%type) as
begin
select count(*) into ret_count from ....;
select min(revision_level) into ret_revision_level from ...;
select revision_name in ret_revision_name...;
return;
end;

Find Sybase stored procedure in db given a text string that appears in the proc

How do I find a stored procedure in a Sybase database given a text string that appears somewhere in the proc? I want to see if any other proc in the db has similar logic to the one I'm looking at, and I think I have a pretty unique search string (literal)
Edit:
I'm using Sybase version 11.2
Two variations on Graeme's answer (So this also won't work on 11.2):
This lists the name of the sproc too, but will return multiple rows for each sproc if the text appears several times:
select object_name(id),* from syscomments
where texttype = 0 and text like '%whatever%'
This lists each sproc just once:
select distinct object_name(id) from syscomments
where texttype = 0 and text like '%whatever%'
In SQL Anywhere and Sybase IQ:
select * from SYS.SYSPROCEDURE where proc_defn like '%whatever%'
I'm not that familiar with ASE, but according to the docs (available from sybooks.sybase.com), it's something like:
select * from syscomments where texttype = 0 and text like '%whatever%'
Please remember, that text column in syscomments is varchar(255), so one big procedure can consist of many lines in syscomments, thus, the above selects will not find the procedure name if it has been splitted into 2 text rows in syscomments.
I suggest the following select, which will handle the above case:
declare #text varchar(100)
select #text = "%whatever%"
select distinct o.name object
from sysobjects o,
syscomments c
where o.id=c.id
and o.type='P'
and (c.text like #text
or exists(
select 1 from syscomments c2
where c.id=c2.id
and c.colid+1=c2.colid
and right(c.text,100)+ substring(c2.text, 1, 100) like #text
)
)
order by 1
-- kudos for this go to the creator of ASEisql
select * from sysobjects where
id in ( select distinct (id) from syscomments where text like '%SearchTerm%')
and xtype = 'P'
select distinct object_name(syscomments.id) 'SearchText', syscomments.id from syscomments ,sysobjects
where texttype = 0 and text like '%SearchText%' and syscomments.id=sysobjects.id and sysobjects.type='P'
Multiple rows are used to store text for database objects the value might be accross two rows. So the more accurate answer is:
select distinct object_name(sc1.id)
from syscomments sc1
left join syscomments sc2
on (sc2.id = sc1.id and
sc2.number = sc1.number and
sc2.colid2 = sc1.colid2 + ((sc1.colid + 1) / 32768) and
sc2.colid = (sc1.colid + 1) % 32768)
where
sc1.texttype = 0 and
sc2.texttype = 0 and
lower(sc1.text + sc2.text) like lower('%' || #textSearched || '%')

Resources