"P1: begin" and "P2: begin" in a DB2 Stored Procedure - stored-procedures

Can anyone explain to me or point me to some documentation on why the stored procedures are tagged into different parts using "P1: begin" and "P2: begin" ?
Thanks,
Mike

An SQL Procedure is defined by the routine-body. The routine-body is defined by\as one SQL Statement, which for a SQL Procedure is typically defined by one compound-statement, yet a compound-statement may be nested within another. Each label:Begin establishes the beginning of a new compound statement; one defined within another would be a nested compound statement. The following is a doc link that may satisfy as an answer to the question; a doc snippet is included which describes the primary purpose as scoping, and I added emphasis on each entity that is scoped:
http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/db2/rbafzsummaryscope.htm
Summary of ′name′ scoping in nested compound statements
Nested compound statements can be used within an SQL routine to define the scope of SQL variable declarations, cursors, condition names, and condition handlers.
Additionally, labels have a defined scope in the context of nested compound statements. However the rules for name space, and how non-unique names can be referenced, differs depending on the type of name. The following table summarizes these differences.
[...]

Related

Generic itab in JOIN in SELECT?

I have a generic table in global area and i want to use it in SELECT from. Is this possible or is there a way do this ?
Example Code:
FIELD-SYMBOLS: <gt_data> TYPE STANDARD TABLE.
CLASS-DATA: mo_data TYPE REF TO data.
CREATE DATA mo_data LIKE lt_data.
ASSIGN mo_data->* TO <gt_data>.
<gt_data> = lt_data.
SELECT data~matnr,
mbew~malzeme_deger
FROM zmm_ddl_mbew AS mbew
INNER JOIN #<gt_data> AS data ON data~matnr EQ mbew~matnr
INTO TABLE #DATA(lt_mbew).
If the Generic table you are asking about is an internal Table which the code snippet suggests, then
No i dont think you cant build a join to work on 2 different sources.
Unless there are some new kernel developments, the select statements are converted to DB SQL statements.
ABAP 7.5 documentation of Select statement refers to the from "data_source" as dbtab,View or cds_entity as possible sources.
Even if it was possible there are still other generic options that may make more sense. If the source internal data is small enough, then you can build a generic where clause to solve the problem.
Select from DBTAB where (string_cond).
If the size of the internal table is so large that you end up with half the data in memory and half on a DB, there may be a better generic solution anyway.
No, it is not possible. From the SELECT datasource help:
If the FROM clause is specified statically, the internal table cannot be a generically typed formal parameter or a generically typed field symbol. Objects like this can only be specified in a dynamic FROM clause and must represent a matching internal table at runtime
The above rule remains valid whether itab joined with dbtab or not.

Implementing a unique surrogate key in Advantage Database Server

I've recently taken over support of a system which uses Advantage Database Server as its back end. For some background, I have years of database experience but have never used ADS until now, so my question is purely about how to implement a standard pattern in this specific DBMS.
There's a stored procedure which has been previously developed which manages an ID column in this manner:
#ID = (SELECT ISNULL(MAX(ID), 0) FROM ExampleTable);
#ID = #ID + 1;
INSERT INTO Example_Table (ID, OtherStuff)
VALUES (#ID, 'Things');
--Do some other stuff.
UPDATE ExampleTable
SET AnotherColumn = 'FOO'
WHERE ID = #ID;
My problem is that I now need to run this stored procedure multiple times in parallel. As you can imagine, when I do this, the same ID value is getting grabbed multiple times.
What I need is a way to consistently create a unique value which I can be sure will be unique even if I run the stored procedure multiple times at the same moment. In SQL Server I could create an IDENTITY column called ID, and then do the following:
INSERT INTO ExampleTable (OtherStuff)
VALUES ('Things');
SET #ID = SCOPE_IDENTITY();
ADS has autoinc which seems similar, but I can't find anything conclusively telling me how to return the value of the newly created value in a way that I can be 100% sure will be correct under concurrent usage. The ADS Developer's Guide actually warns me against using autoinc, and the online help files offer functions which seem to retrieve the last generated autoinc ID (which isn't what I want - I want the one created by the previous statement, not the last one created across all sessions). The help files also list these functions with a caveat that they might not work correctly in situations involving concurrency.
How can I implement this in ADS? Should I use autoinc, some other built-in method that I'm unaware of, or do I genuinely need to do as the developer's guide suggests, and generate my unique identifiers before trying to insert into the table in the first place? If I should use autoinc, how can I obtain the value that has just been inserted into the table?
You use LastAutoInc(STATEMENT) with autoinc.
From the documentation (under Advantage SQL->Supported SQL Grammar->Supported Scalar Functions->Miscellaneous):
LASTAUTOINC(CONNECTION|STATEMENT)
Returns the last used autoinc value from an insert or append. Specifying CONNECTION will return the last used value for the entire connection. Specifying STATEMENT returns the last used value for only the current SQL statement. If no autoinc value has been updated yet, a NULL value is returned.
Note: Triggers that operate on tables with autoinc fields may affect the last autoinc value.
Note: SQL script triggers run on their own SQL statement. Therefore, calling LASTAUTOINC(STATEMENT) inside a SQL script trigger would return the lastautoinc value used by the trigger's SQL statement, not the original SQL statement which caused the trigger to fire. To obtain the last original SQL statement's lastautoinc value, use LASTAUTOINC(CONNECTION) instead.
Example: SELECT LASTAUTOINC(STATEMENT) FROM System.Iota
Another option is to use GUIDs.
(I wasn't sure but you may have already been alluding to this when you say "or do I genuinely need to do as the developer's guide suggests, and generate my unique identifiers before trying to insert into the table in the first place." - apologies if so, but still this info might be useful for others :) )
The use of GUIDs as a surrogate key allows either the application or the database to create a unique identifier, with a guarantee of no clashes.
Advantage 12 has built-in support for a GUID datatype:
GUID and 64-bit Integer Field Types
Advantage server and clients now support GUID and Long Integer (64-bit) data types in all table formats. The 64-bit integer type can be used to store integer values between -9,223,372,036,854,775,807 and 9,223,372,036,854,775,807 with no loss of precision. The GUID (Global Unique Identifier) field type is a 16-byte data structure. A new scalar function NewID() is available in the expression engine and SQL engine to generate new GUID. See ADT Field Types and Specifications and DBF Field Types and Specifications for more information.
http://scn.sap.com/docs/DOC-68484
For earlier versions, you could store the GUIDs as a char(36). (Think about your performance requirements here of course.) You will then need to do some conversion back and forth in your application layer between GUIDs and strings. If you're using some intermediary data access layer, e.g. NHibernate or Entity Framework, you should be able to at least localise the conversions to one place.
If some part of your logic is in a stored procedure, you should be able to use the newid() or newidstring() function, depending on the type of the backing column:
INSERT INTO Example_Table (newid(), OtherStuff)

Esper - how to build dissent "statement factory"?

using Esper engine - I find myself write lots of String SQLs, and do lots of string actions to insert query to EPStatement object.
What is the best practice to build queries in more convenient way? maybe build queries not with pure strings but with objects? (Have anyone used EPManagedStatement object?)
There is also the Statement Object Model.
With these classes you can build statements in a more object-oriented way and avoid all the string queries.
Taken from the documentation:
The statement object model is a set of classes that provide an object-oriented representation of an EPL or pattern statement. The object model classes are found in package com.espertech.esper.client.soda. An instance of EPStatementObjectModel represents a statement's object model.
The statement object model classes are a full and complete specification of a statement. All EPL and pattern constructs including expressions and sub-queries are available via the statement object model.
If you find that you are writing a lot of free-form EPL that only varies greatly by the actual values you are inserting, one approach you might find lightens up the amount of code is to use prepared statements ( (EPPreparedStatement). That way, you write the EPL once and then simply issue binds without having to re-specify the text all over again.

Is it possible to call a procedure within an SQL statement?

I thought I would use a stored routine to clean up some of my more complex SQL statements. From what I've read, it seems impossible to use a stored procedure within an sql statement, and a stored function only returns a single value when what I need is a result set. I am using mySQL v5.0
SELECT p.`id`, gi.`id`
FROM `sport`.`players` AS p JOIN `sport`.`gameinstances` AS gi
ON p.`id` = gi.`playerid`
WHERE (p.`playerid` IN (CALL findPlayers`("Canada", "2002")))
AND (gi.`instanceid` NOT IN (CALL findGameInstances`("Canada", "2002")));
For example, the procedures 'findPlayers' and 'findGameInstances' are are stored routines that execute some SQL and return a result set. I would prefer not to include their code directly within the statement above.
I don't know if mysql can use any of these techniques, but in SQl server I would try one of two different things (at least it might give you something to look for in th emysql documentation):
First a table values used defined function then join to that
Second, insert the results set of the sp into a temp table then join to the tem table
You could also consider putting the complicated logic in a view and then just adding the where clause after joining to the view. This won't work if your stored proc does dynamic things a view can't do, but it is a possibilty.

MSSQL2000: Using a stored procedure results as a table in sql

Let's say I have 'myStoredProcedure' that takes in an Id as a parameter, and returns a table of information.
Is it possible to write a SQL statement similar to this?
SELECT
MyColumn
FROM
Table-ify('myStoredProcedure ' + #MyId) AS [MyTable]
I get the feeling that it's not, but it would be very beneficial in a scenario I have with legacy code & linked server tables
Thanks!
You can use a table value function in this way.
Here is a few tricks...
No it is not - at least not in any official or documented way - unless you change your stored procedure to a TVF.
But however there are ways (read) hacks to do it. All of them basically involved a linked server and using OpenQuery - for example seehere. Do however note that it is quite fragile as you need to hardcode the name of the server - so it can be problematic if you have multiple sql server instances with different name.
Here is a pretty good summary of the ways of sharing data between stored procedures http://www.sommarskog.se/share_data.html.
Basically it depends what you want to do. The most common ways are creating the temporary table prior to calling the stored procedure and having it fill it, or having one permanent table that the stored procedure dumps the data into which also contains the process id.
Table Valued functions have been mentioned, but there are a number of restrictions when you create a function as opposed to a stored procedure, so they may or may not be right for you. The link provides a good guide to what is available.
SQL Server 2005 and SQL Server 2008 change the options a bit. SQL Server 2005+ make working with XML much easier. So XML can be passed as an output variable and pretty easily "shredded" into a table using the XML functions nodes and value. I believe SQL 2008 allows table variables to be passed into stored procedures (although read only). Since you cited SQL 2000 the 2005+ enhancements don't apply to you, but I mentioned them for completeness.
Most likely you'll go with a table valued function, or creating the temporary table prior to calling the stored procedure and then having it populate that.
While working on the project, I used the following to insert the results of xp_readerrorlog (afaik, returns a table) into a temporary table created ahead of time.
INSERT INTO [tempdb].[dbo].[ErrorLogsTMP]
EXEC master.dbo.xp_readerrorlog
From the temporary table, select the columns you want.

Resources