Toaz - Info Sap Hana Abap PR
Toaz - Info Sap Hana Abap PR
Toaz - Info Sap Hana Abap PR
First
Program in ABAP HANA
Questions:
3. Seems ADT does the same thing like SE80 T-code. Then why do we really
need ADT?
The below explanations are as per our understanding. We would like to appeal
our experienced ABAPers to throw some more light to the below answers if they
know more about it.
1. HANA as a database has evolved manifold in the last few years. In order to
keep pace with these hardware and software innovations, HANA Studio is
introduced. HANA Studioprovides the right environment for HANA
administration, modeling and data provisioning.
Studio is needed so that the developers can create models, procedures etc
using the Eclipse-based tool in HANA. Studio is also utilized to develop SQL
Script which writes Application logic that would push down data-intensive
queries and logic to HANA database and improves the overall performance of
the system.
Also, the Studio gives freshness to developers who were bored with the blue
GUI screen editor.
Hopefully, you have some idea of HANA Studio and its need.
2. ABAP Development Tool is the full form of ADT. ADT provides eclipse
base ABAP Integrated Development Environment (IDE).
ADT does not come by default. It has to be installed as a plugin on Eclipse (in
Studio -> Help -> Add New Software).
We need ADT because with ADT in Eclipse, the HANA Studio becomes super
powerful. You can connect to different ABAP systems from single Eclipse
User Interface. Isn’t it cool? With ABAP perspective in the studio, you
can implement end-to-end in-memory solutions in Studio with the same UI.
One entry point and multiple benefits. Don’t you like it?
3. You are right. Both ADT and SE80 have same source code repository and
locking mechanism and thus both compliment each other. But ADT is more
powerful than SE80. Some advanced features like creating external views for
exposing HANA view to ABAP DDIC* (external views), creating Database proxy
procedures* are available only when using ADT.
SE80 has been with SAP from birth. ADT is new and still has some enhanced
features. SAP is continuously working on more exclusive features which would
be possible only from ADT in future. So, ADT is the future
Bonus question
ABAP project helps to connect the Eclipse base IDE to ABAP backend
system. The project provides eclipse based frameworks for creating, processing
and testing development objects.
In short, ABAP project represents a system logon and contains all ABAP
development objects of the related system.
Check this image below. Project S4H_800_SIMPLE3_SAPYARD is our project
which is connected to our S4H system.
Similarly, we can have multiple projects pointed to multiple systems from
one HANA Studio UI.
7. No, we cannot edit the same program simultaneously. Both ADT and SE80
have same source code repository and locking mechanism (as mentioned in
answer 3), therefore, we cannot interfere when other is editing it at the same
time.
You get the below error in ADT if you try to edit the already opened program (in
GUI).
Finally, the much-awaited question by the ABAPer..
Q. How can we write ABAP programs using ADT and execute it?
8. Select the Package where you want to save your program. Right-click on it
and select ABAP Program.
Give the name and description of the program. Do not forget, the Z* or Y*
naming convention holds good even while creating custom objects from ADT.
You need to choose the transport where you want to save your program.
Write your program and check the syntax and activate it. Most of the icon are
similar to GUI. Done, your program is ready in Studio. Actually, you created the
program just like in SE38/SE80, just the front end was different. You can go to
your ABAP system and check, the new program exists there.
Execute the RUN icon in HANA studio and your program would show the output.
Congrats, you created your first program in SAP HANA and executed it
successfully. Although this was a dummy program, in actual projects as well,
the process remains the same.
Also Read: SAP HANA ; S/4 HANA and S/4 HANA Finance in Nutshell
Please stay tuned for more ABAP on SAP HANA technical stuff.
Happy Learning.
Next Post: SAP ABAP for HANA. Part II. ADT Eclipse and HANA Studio
In the SAP ABAP on HANA Part I, we talked about some common questions
and answers. We also created our first program in HANA Studio. In this article,
we would get accustomed with the HANA Studio screen, various buttons and
icons. How/Why to use them and also we would try to correlate the
functionalities of HANA screen icons to that of classic GUI icons.
1. Change/Display Icon
We were not able to figure out the change/display toggle icon in HANA Studio
ABAP editor. Whenever we opened the program in our development system, it
opened in change mode. If any reader knows about the change/display icon (or
shortcuts) in eclipse, please do mention it in the comment section or email us
and educate all.
2. Pattern Icon
Another significant button which we could not figure out in HANA Studio is the
Pattern Icon. When we want to auto generate the FM/Class/Method or any
custom pattern, we are so habituated to use this Pattern icon in ABAP
editor. We were little surprised, not to find this commonly used button. But you
need not be disappointed. Type initial letters of the syntax you want to use and
then use Ctrl + Space and Shift + Enter to insert the full signature(e.g. for
function module / method selected).
3. Pretty Printer
There is no pretty printer icon. How would developers impress their team leads
and quality reviewers without the pretty printer?
Do not worry, the pretty printer button might not be there, but the functionality
still exists. Go to Windows -> Preference -> ABAP Development ->
Source Code Editor -> Formatter to set up the formatting needs.
You might not see the Formatter option upfront. You need to click on Source
Code Editors. Then you would see settings for different options (number 5 in
above image) and Formatter is one of them.
Once you set the format, Shift + F1 is the shortcut for the desired formatting.
These are some commonly used icons/buttons which are missing in Eclipse ADT.
Please note, this is not the whole elaborate list.
[ad1ToAppearHere]
1. Outline View
Let us start with the Outline View in HANA Studio. Check the outline view on the
lower left corner of the studio.
The Outline view displays the internal structure of a program or class that
is currently open in the ABAP source code editor. The Outline view is synonyms
to the Object detailed screen of ABAP editor in SE80. Just like when we click any
element on SE80, it takes to that element in the main program, similarly, the
outline is synchronized with the contents of the editor. Hence, when an element
in the Outline view is selected, we can navigate quickly to the corresponding
position in the ABAP source code.
Just like in SE80 editor, for each element in Outline View in Studio, we can
navigate to the declaration part in the source code editor or the implementation
part (e.g. in the case of methods of a class).
2. Keyword Completion/Suggestion
Just like in GUI, ABAP editor on HANA studio suggests keywords as you type the
syntax. The GUI shortcut Ctrl +Space holds good in eclipse too.
3. Where-Used List
4. Revision History.
Like in GUI ABAP editor, we can compare changes from one transport of source
code to another in ADT. Right click on the source code area of the program and
choose Compare with -> Revision History.
4. Transport Organizer
Transport Organizer in ADT for Eclipse enables ABAP developers to perform the
below Transport related operation through Studio.
[ad2ToAppearHere]
Check the red cross on the left side of the code editor. This feature warns you
of any error lines while you are typing your program and even before you hit
the syntax checker. This comes really handy for the ABAPers to type the right
syntax as and when he/she is.
Although we have Find and Replace (or Ctrl + H) option in SAP GUI, but
Eclipsed based ADT has better renaming experience. Just right click on the
source editor and select Rename or hit Alt+Shift+R, to open the replace
wizard.
Select the element you want to replace and hit Rename (Alt+Shift+R), give the
new name for the element and hit Next.
Before it finishes, it would show the Original code and the new code after the
change. It would also show all the lines which would be changed.
Hit Finish and the element is renamed throughout the entire source code.
[ad3ToAppearHere]
In ABAP on SAP HANA Part II, we made ourselves comfortable with the
HANA Studio screen, icons and buttons. In this article, we will get exposed to
Breakpoints and Debugging in ADT. If you have been working as an ABAPer for
some time, it would not take much time for you to get familiar with
the Debugger in ADT (Eclipse/HANA Studio). It the same wine in new bottle.
ABAP debugger is completely integrated with Eclipse from Kernel 7.21, SAP
Basis 7.31 SP4.
All the standard debugging features which were earlier available in GUI editor
are also available in eclipse. Such as:
i) Set breakpoints
1. Static Breakpoint
Static breakpoints are set at a particular line of the code. A static breakpoint
stays with the line of code at which you set it. If you delete code lines above the
breakpoint, it slides along with the relocated code at that particular line.
2. Dynamic Breakpoint
Dynamic breakpoints are determined at run time. They are triggered when the
running program reaches a particular ABAP statement e.g. loop, perform,
select, calls, submits etc.
Please note: Dynamic breakpoints take effect for all programs that run under
your user. You need to be careful to remove the dynamic breakpoint once you
have finished your analysis. Or else, it would stop for any application where the
dynamic breakpoint condition is found. And we are sure, you do not want speed
breakers in a highway.
We can always limit the scope of dynamic breakpoints to the scope of the
debugger.
[ad1ToAppearHere]
Hands On Section:
Enough of preaching!! Well, above are the theories and I am sure you would be
more interested in looking at the actual screens. Let us have a quick look at the
Debugger screen and substantiate our understanding.
Resume button : Run to the next breakpoint or to the end of the program.
Terminate button : Abort the execution of the program in the debugger.
Program execution ends.
Disconnect button : Run to the end of the program, ignoring any intervening
breakpoints.
Step Into (F5) button : Execute the next single ABAP instruction in the program
in the debugger.
Step Over (F6) button : Execute the next ABAP statement. If the next step is a
procedure call, run the entire procedure.
Step Return (F7) button : Run until the current procedure returns to its caller or
until the program ends.
Run to Line (Shift F8) button : Run to the statement on which the cursor is
positioned. Breakpoints in between will be respected or not is set in Windows-
>Preferences->ABAP Development->Debug.
Double click on the area shown below or right click and choose Toggle
Breakpoint or press Ctrl + Shift + B.
3. Execute the program
You would get this pop-up. Select OK and continue. The debugger stops at the
breakpoint.
You can change the values of variables at the run time as you used to do in
ABAP GUI debugger. You can also move the cursor over the variable to display
its value.
[ad2ToAppearHere]
Double click on the internal table name and see the values in the internal table
view.
You can also right click on the internal table name and choose Open Data
Preview to see the values of the internal table.
[adToAppearHereLink]
6. Let’s set a Dynamic Breakpoint
Go to the Breakpoints View and Add dynamic breakpoints at the statements you
need. Type the statment in the search area and get your dynamic statements.
Manage breakpoints using Breakpoints View. Right click on the breakpoint and
choose the Breakpoint Properties and choose the restriction you want.
8. Manage the Debug Properties for the user/session
You can change the user for which external breakpoints are effective.
Breakpoints cab also be effective for the entire project independent of the
users.
Hopefully, this article was successful in giving you the overview of Debugging in
HANA ADT. For experienced ABAPers, it is the same thing as in ABAP GUI, with
some good additions. For freshers, you need some system to get your hands
dirty and learn.
As declared in our previous post, we are planning to allow our subscribers’ free
access to SAP HANA system for a couple of hours to get the look and feel of
the system for free (for a couple of hours only). We are still compiling the list.
After we get the total list of interested users, we would provide the credentials
and date/time when they can access it. In the next article, we would see how
we can perform ABAP Profiling/Tracing in Eclipse Studio and more.
Next Post: SAP ABAP HANA Tutorial. Part IV. Core Data Services
Let us start our encounter with Core Data Services (CDS) View with
questions and answers. Before we explain What is CDS View, let us ask, Why
CDS View?
Question: Why do we really need CDS Views?
Say our requirement is to get the id, name and the respective zip code of the
home address for all employees in org_unit ‘4711’.
The issue with the above SQL: Large Semantic Gap between Requirement
and SQL Code.
If you are not an experienced SQL developer, you would find it complex/difficult
to understand the meaning/semantic of the SQL. Therefore SAP wanted
something simpler and better. This is one motivation for CDS.
Being an ABAPer you find the above SQL complex and you decide to write your
own Open SQL in ABAP.
Issue with the above Open SQL: SQL Complexity Leads to Imperative
Code (codes which are like instructions/statements which change its state.
Imperative programming focuses on describing how a program operates.)
There are performance concerns in the above Open SQL. Loops in loops, nested
queries with many round trips is not advisable. This is another motivation for
CDS.
Same requirement: Get the id, name and the respective zip code of the home
address for all employees in org_unit ‘4711’.
With CDS, SQL developers see small or no semantic gap and ABAPers do not
need any coding. You get the result directly from the CDS. Isn’t this
motivation enough?
[ad1ToAppearHere]
Answer: CDS is much more powerful than what it appears. The CDS concept is
far more than simple view building but describes a DDL for building a meta-
model repositoryinvolving database tables, database views, functions, and data
types.
With “HANA CDS”, CDS is available for SAP HANA in the SAP HANA studio. With
“ABAP CDS”, the CDS concept is also made available for the AS ABAP, where
the features of CDS surpass the modeling capabilities of SE11. ABAP CDS is
open and not restricted to SAP HANA (i.e. database independent).
If we need meta-models for our application, that can be built with CDS, then we
need CDS views.
Question: OK, we read above that CDS was invented to facilitate needs which
ABAP Dictionary and HANA Studio could not meet. So, what are the types of
CDS Views?
1. ABAP CDS
2. HANA CDS
(We will check the details of CDS View with and without Parameters in our next
article)
Answer: With CDS, data models are defined and consumed on the
database rather than on the server. CDS also offers capabilities beyond the
traditional data modeling tools,including support for conceptual modeling and
relationship definitions, built-in functions, and extensions. Originally, CDS was
available only in the design-time and runtime environment of SAP HANA. Now,
the CDS concept is also fully implemented in SAP NetWeaver AS ABAP, enabling
developers to work in the ABAP layer with ABAP development tools while the
code execution is pushed down to the database.
Similar to the role of the DDIC in the traditional ABAP world, data models based
on CDS serve as central definitions that can be used in many different domains,
such as transactional and analytical applications, to interact with data in the
database in a unified way . However, CDS data models go beyond the
capabilities of the DDIC, which were typically limited to a transactional scope
(think of traditional online transaction processing functionality). For example, in
CDS, you can define views that aggregate and analyze data in a layered
fashion, starting with basic views and then adding powerful views that combine
the basic views. Another difference is the support for special operators such as
UNION, which enables the combination of multiple select statements to return
only one result set.
CDS artifacts are stored in the DDIC and can be accessed in ABAP programs via
Open SQL in the same manner as ordinary ABAP tables or views.
Also Read: Create you first SAPUI5 App and Consume a Custom OData Service
without any code
In simple words:
Core data services are a new infrastructure for defining and consuming
semantically rich data model in SAP HANA. Using a data definition language
(DDL), a query language (QL), and an expression language (EL), CDS is
envisioned to encompass write operations, transaction semantics, constraints,
and more .
We can use the CDS specification to create a CDS document which defines the
following artifacts and elements:
Entities (tables)
Views
Contexts
Associations
Annotations
[ad2ToAppearHere]
Answer: The subtle differences between CDS in native SAP HANA and CDS in
ABAP lies in the view definition. In both the ABAP and HANA scenarios, views
are created on top of existing database tables that are contained in the
DDIC. With CDS in native SAP HANA, we must create the basic entity types that
correspond to the DDIC tables as part of the CDS view definition. With CDS in
ABAP, we can refer to any underlying DDIC table, view, or type from within the
CDS view definition, avoiding the need to “duplicate” the DDIC table definitions
on the CDS layer. In the ABAP scenario, the CDS definitions are considered
DDIC artifacts and need to be activated like any other DDIC artifact and when
changes are made, their impact is propagated to dependent artifacts.
Answer: If you use ABAP on HANA DB, you can work directly on the DB and also
use HANA CDS there. But then the CDS objects created are not managed by the
ABAP Dictionary meaning you cannot access them directly with Open
SQL and they are not TYPEs in the ABAP TYPE system.
Question: When should we use ABAP CDS and when should we use HANA
CDS?
If you have an ABAP stack on top of a HANA database (an AS ABAP uses the
HANA database as central database) then:
i) If you want to access the CDS entities in ABAP as data types or in Open SQL
or if you want to evaluate the CDS annotations in ABAP, you must use ABAP
CDS.
ii) If you do not want to access the CDS entities in ABAP, but you want to
transport and upgrade them like ABAP repository objects, you can use ABAP
CDS.
iii) If you do not want to access the CDS entities in ABAP as data TYPEs or in
Open SQL, you can use HANA CDS, which is better integrated into SAP HANA.
An access from ABAP is then possible using Native SQL (ADBC, AMDP) only.
Answer: Yes we can. For each CDS view a database view (SQL view) is created
in the database during activation. We can access that database view natively if
we want to. CDS table functions are managed by AMDP. The respective
database functions can also be accessed natively.
Answer: Yes. Open SQL checks the authorization implicitly but is of course
translated into native SQL code doing that on DB level (implicit conditions).
Same for the SADL framework that checks the authorizations itself natively. The
problem is that you need to have access to the internal role representation
which is not published and subject to change or you have to build a framework
yourself that parses the role definition and creates the corresponding
conditions.
Answer: Check the table TADIR in SE16; PGMID = ‘R3TR’, OBJECT = ‘DDLS’;
here we find all DDL sources and the package of each source in column
DEVCLASS. Knowing the package, we can use ADT (ABAP Development Tool in
HANA Studio) to find the DDL sources in ADT.
Now, let us open the DDL SQL View of the CDS. Note the warning below which
says DDL SQL views are only supported in a limited way by SE11.
Having one name is just not good enough in CDS; we need two names.
One name is for the SQL view that is going to be created in the dictionary (the
one we will be able to look at in SE11), and the other name we have is a name
for the CDS view entity, which is viewed and changed via Eclipse.
PS: We could name both the SQL view and the CDS view the same, but we
should not as they are different things, so the name should reflect the
difference.
CDS View entity is the one we should refer to in SELECT statements in our
ABAP programs. Although we can use DDL SQL View in our programs, but we
should not.
Question: How can we use CDS views?
Answer: Basically, a CDS View is an entity that can be addressed by its name:
in ABAP as a TYPE
Basically, a CDS View is an entity that can be addressed by its name in ABAP as
a TYPE in Open SQL as a data source
Seeing a CDS View in SE11 is kind of a technical artifact and we should not
address the database view that is shown there in our ABAP programs. From
SE11 you can also navigate to the database object that is generated from the
definition. This database object can even be accessed directly with Native SQL.
This means we can access our CDS Views directly in ABAP programs or from
elsewhere. For evaluating the semantic properties (annotations) of a CDS View
(stored in system tables) we should use an appropriate API
(CL_DD_DDL_ANNOTATION_SERVICE if available in your system).
The database views created from the CDS source code are merely “for
technical” reasons. The CDS source code and the CDS entity defined there
should be the “real thing”.
13 Extensible
[ad3ToAppearHere]
SAP claims that whereas a traditional database view is just a linkage of one or
more tables, a CDS view is a fully fledged data model, which, in addition to
having extra features that SE11-defined views do not, can be used even by
applications outside of the SAP domain.
Note: We cannot do OUTER JOINs in an SE11 database view (just one limitation
to point which CDS can overcome).
iii) Expressions used for calculations and queries in the data model
CDS views, like the well-known dictionary views created and maintained in
transaction SE11, are managed by the ABAP data dictionary. During activation,
a database view is created on the HANA layer, yet only the ABAP CDS
view (defined in a so-called DDL source) has to be transported via the ABAP
Change and Transport System (CTS). Moreover, the functionality provided by
CDS views can be used on all SAP supported databases, we don’t have to worry
when transporting these objects in a heterogeneous system landscape.
CDS views are entities of the ABAP CDS in the ABAP Dictionary that are much
more advanced than the classical SE11 views. We can influence CDS views
with parametersthat can be used at different positions of the DCL. As for
classical SE11 views, for a CDS View, a platform dependent runtime object is
generated at the database that we can examine in SE11. When accessing a
(CDS) view with Open SQL (i.e ABAP), the database interface accesses
this runtime object. A CDS view is created with a source code basededitor in
Eclipse using a DDL (which ha nothing to do with SQLScript).
For technical reasons, from the source code a classical DB view is generated in
SE11 that we can access like any classical view, but we shouldn’t. Instead, the
so-called CDS entity should be accessed because it carries more meaning
than the mere technical DB view and involves new kind of client handling.
PS: In an upcoming release, the direct access to the DB view of a CDS view will
be declared as obsolete. So, better not to use them if it can be avoided.
We use CDS to model large parts of our application in the Dictionary and use
simple Open SQL SELECTs in ABAP for relatively straight joins and subqueries in
ABAP. Some day Open SQL might have the same power like CDS but it doesn’t
mean that those are redundant. Already before CDS, we had the choice
between creating a reusable view in SE11 or programming a join in Open SQL in
ABAP. As a rule of thumb, we created a view if it is used in more than one
program and programmed a join when we needed it only once. That is very
similar for CDS, but with much more possibilities for modeling semantically rich
models for reuse in ABAP programs.
Hope these Q&A would help to clear out some cobwebs regarding Core Data
Services. In the subsequent articles, we would show how we can create the CDS
Views and use them in ABAP Programs.
In our previous post on ABAP on SAP HANA Part IV, we tried to understand
why SAP came up with CDS Views when database views and other views were
already there. We learned the need of Core Data Services and it’s advantages
and its possible usage.
In this article, we would dive a little deeper on CDS View from an ABAPer’s
perspective.
DDL SQL View : It is read-only classical database view which is visible in ABAP
Dictionary (SE11). It cannot be edited in SE11.
CDS View Entity: It is the DDL Source File and the actual CDS View. It is
a Database Object which is visible in Eclipse/HANA Studio/ADT and we cannot
view CDS View Entity in SE11. It covers the CDS Database view and makes
other attributes possible, such as authorization checks defined in CDS view.
Before I show, how CDS View is created in HANA ADT, let me start with,
how CDS View can be deleted.
Question: Do we need to delete both the Dictionary DDL SQL and CDS
View individually?
Answer: No.
Answer: No.
Check the below image, I am trying to delete the DDL SQL which is created
when CDS View is created.
HANA does not allow me to delete this independently. ‘Generated DDL SQL
views cannot be deleted’.
So we are left with CDS View entity. And you guessed it right. Check the below
images, we can delete CDS View entity.
Question: What happens to DDL SQL View when CDS View (DDL Source)
is deleted?
DDL SQL is automatically deleted when the CDS View is deleted. Check the
image below, both are deleted in one go.
In all other tutorials, you would see that DDL Source is below Dictionary. In our
image above, check it is below Core Data Services folder. HANA and SAP are
evolving at great pace. We need to keep up with their pace.
The above images are self-explanatory. Let us pause at the final step of the
wizard. As of now, SAP is kind enough to provide six templates for creating
the CDS View as per our need. ABAPers feared they might not be able to learn
SQL and remember the syntaxes. Look, SAP already thought for us. ABAPers
are not going anywhere.
In most of the tutorials on CDS View in other blogs, you might have seen only
first 5 templates. You would find the sixth template “Define Table Function
with Parameters” now. SAP and HANA innovation team are really fast (like
their in-memory system)
. When you actually get a chance to make your hand dirty in HANA ADT, do not
be surprised if you find more that 6 templates.
Let us select the first template Define View and hit Finish button.
Here system expects us to christen our DDL SQL View Name. We also need to
provide the data_source_name (i.e the table or view from where data would be
selected). As pointed out in the previous article, it is a good idea to separate
SQL View Name and actual CDS View Name. For consistency, we name SQL
View Name with DDLS and CDS View with CDSV. You might have a
different naming convention in your project.
For our example the SQL View Name is YDDLS_WO_STAT and CDS View is
YCDSV_WO_STATUS.
Also Read: Create your first SAPUI5 and Consume Custom OData Service with
NO code
Food for thought for all ABAPers
What is the maximum length of the name which we can give to the SQL
View Name?
Look at the first four auto-generated lines. They precede with “@”. They are
called “Annotation”.
Also, check the Outline window section in the left side corner. It shows the CDS
views breakups. source data table / view, CDS View key and field list.
No problem to view it. We can even display the data pulled by the view.
Also Read: Know SAP HANA Studio/ADT/Eclipse icons/buttons.
Ok, while creating the CDS View, it asked for the transport where we wanted to
save our generated objects. What do you think, did both DDL SQL View and
CDS View entity get saved in that transport? Or do you think otherwise?
All change objects and transports are managed in the ABAP layer end to
end. We do not need to go to the lower underlying database (HDB) level to
manage the transport of CDS entities/artifacts.
While creating the new CDS View, let us select the Define View with
Join template. As discussed, we need to type our ABAP Dictionary (DDL) SQL
View name. In addition, we need to replace the auto-generated
data_source_name and joined_data_source_name along with its element
names.
For our example, we have joined the Status table and Status text. Join is the
same as we have been doing in ABAP.
ABAPers are familiar with the term Parameter. Just like we can have
PARAMETERs in the selection screen of a report, similarly we can have
Parameters on CDS Views. Do not be too optimistic, we do not have SELECT
OPTION in CDS View till now.
We know, Parameter helps to filter the data and is useful in WHERE Clause.
CDS View with Parameters is normally created to filter the data during selection
process at database level itself (i.e additional filtration is done using CDS View
with Parameters). So, there is no need to put additional filtering (where
condition) at ABAP Layer. Code to Data shift (one of the motivations of Core
Data Services).
Choose the template Define View with Parameters and provide the DDL SQL
View name (data dictionary) and data source name as done in above examples.
In addition to that, provide the parameter name and parameter type. We
can have multiple parameters in a CDS View, separated by a comma.
Check the usage of parameters in the above image. If we define CDS View with
multiple parameters separated by a comma, we can have multiple parameters
in the WHERE Clause separated by AND/OR. Also, note that “$” sign needs to
be provided with parameters while using it in WHERE Clause.
1
2 with parameters p_stat: j_status,
3 p_lang: spras
4
5 WHERE jcds.stat = $parameters.p_stat and tj02t.spras = $parameters.p_lang;
Les us see the DDL SQL View (data dictionary) for this CDS View with
Parameter and try to display the content output for this CDS View.
Opps. Data display for views with parameters is not yet supported.
Hopefully, SAP would come up with this option too in near future.
There are other templates like View with Association, Extend View and Table
Function with Parameters. We can cover them some other day. If you cannot
wait, please check this external link. This has the exhaustive demonstration of
different CDS Views and its capabilities.
The last thing we want to cover today is how to consume a CDS View in ABAP
Program.
We can use the CDS View like any other table or data dictionary view in ABAP. I
found the usage of CDS View with Parameters little tricky. Please check the
below code snippet for usage of CDS View with Parameters. Let me accept up
front that the below program does not show the real power of CDS View. It is
only for demonstration.
1
2 SELECT * FROM ycds_wo_stat_txt_para( p_stat = @p_status ) INTO TABLE @i_wo_status.
You would notice below that “@” symbol is used for escaping of host
variables. They help to identify ABAP work areas/variables/constants in
Open SQL statement. Literals need not be escaped using “@”. If we decide to
escape one host variable, all host variables should be escaped.
Also, we can select from both DDL SQL View and CDS View. So, we need to
declare the internal tables/work areas according to the View you intend to
use. Although DDL SQL View and CDS View are mirror images still you cannot
use the TYPE statement interchangeably in the program.
Also Read: End to End Config and Implementation of Two Fiori Apps with NO
code
Answer: If we consume DDL SQL View in ABAP SELECT statement, then, it will
act as any other normal view/table which is created in data dictionary using
SE11. We would not be taking real advantage of HANA. We would not see the
performance improvement. Theoretically, when the DDL SQL View is used, a
database connection from ABAP Layer to Database Layer is established and this
process would consume some resources for database connection (even though
your database in HANA).
Question: Why is it good practice to use CDS View Entity (DDL Source)
while using ABAP SELECT statement?
Answer: By now we have a fair idea that CDS View Entity (DDL Source) is a
database object which is known to ABAP Layer and does not exist in data
dictionary (SE11). This database object contains SQL power and resides
at the database layer.Consumption of CDS View by DDL Source name invokes
Database Object which is residing at Database Layer i.e., SQL inside the DDL
Source Name at Database layer (DDL Source). This way, we can execute an
SQL without creating a database connection between ABAP Layer and Database.
Only results will be transferred back to ABAP layer. This will save resources for
creating a database connection from ABAP Layer to Database Layer.
I would like to request HANA Experts to provide some more insight and
justification of using CDS View Entity (DDL Source) in SELECTs.
1
2 *&---------------------------------------------------------------------*
3 *& Report YCDS_WO_STATUS_REPORT
4 *&---------------------------------------------------------------------*
5 *& Description: Demo to fetch data from CDS View with Parameter
6 *& Note: This program is just to show how CDS View can be used.
7 *& This does not depict the true strength (Core to Data Paradigm) of CDS
8 *&---------------------------------------------------------------------*
9 REPORT YCDS_WO_STATUS_REPORT.
10
11 *--------------------------DATA DECLARATION----------------------------*
12 DATA: i_wo_status TYPE STANDARD TABLE OF ycds_wo_stat_txt_para. " CDS Entity View
13 * DATA: I_WO_STATUS TYPE STANDARD TABLE OF YDDLS_WO_STAT_PA. " DDL SQL View
14 (DDIC)
15
16 *&---------------------------------------------------------------------*
17 *&SELECTION SCREEN
18 *&---------------------------------------------------------------------*
19 SELECTION-SCREEN BEGIN OF BLOCK a01 WITH FRAME TITLE text-001.
20 PARAMETERS : p_status TYPE j_status. " Status
21 SELECTION-SCREEN END OF BLOCK a01.
22
23 *&---------------------------------------------------------------------*
24 *& START OF SELECTION.
25 *&---------------------------------------------------------------------*
26 START-OF-SELECTION.
27
28 * Select data using CDS View with Parameter
29 PERFORM sub_get_data_from_cds.
30
31 *&---------------------------------------------------------------------*
32 *& END OF SELECTION.
33 *&---------------------------------------------------------------------*
34 END-OF-SELECTION.
35
36 * Display data
37 PERFORM sub_display_data.
38
39 *&---------------------------------------------------------------------*
40 *& SUB ROUTINES
41 *&---------------------------------------------------------------------*
42
43 FORM sub_get_data_from_cds.
44 * Fetch from CDS Entity View
45 SELECT * FROM ycds_wo_stat_txt_para( p_stat = @p_status ) INTO TABLE @i_wo_status.
46
47 * Fetch from DDL SQL data dictionary View
48 * SELECT * FROM YDDLS_WO_STAT_PA( P_STAT = @P_STATUS ) INTO TABLE
49 @I_WO_STATUS.
50 ENDFORM.
51
52 FORM sub_display_data.
53
54 DATA:
55 lv_status_rel TYPE j_status VALUE 'I0002', " Release Status
56 lr_functions TYPE REF TO cl_salv_functions, " ALV Functions
57 lr_alv TYPE REF TO cl_salv_table, " ALV Functions
58 lr_display TYPE REF TO cl_salv_display_settings, " ALV Functions
59 lv_salv_msg TYPE REF TO cx_salv_msg. "ALV Functions.
60
61 * Display the final internal table in ALV
62 IF i_wo_status IS NOT INITIAL.
63 TRY.
64 * Factory Method
65 cl_salv_table=>factory( IMPORTING r_salv_table = lr_alv
66 CHANGING t_table = i_wo_status ).
67
68 CATCH cx_salv_msg INTO lv_salv_msg.
69 MESSAGE lv_salv_msg TYPE 'E'.
70
71 ENDTRY.
72
73 * Self explanatory
74 lr_functions = lr_alv->get_functions( ).
75
76 lr_functions->set_all( abap_true ).
77
78 lr_display = lr_alv->get_display_settings( ).
79
80 lr_display->set_striped_pattern( cl_salv_display_settings=>true ).
81
82 lr_display->set_list_header( text-001 ).
83
84 * Actual Diplay
85 lr_alv->display( ).
86
87 ELSE.
88 MESSAGE 'No data found' TYPE 'I'.
89 LEAVE LIST-PROCESSING.
90 ENDIF.
ENDFORM.
Please check this video from abap channel. This video speaks about CDS
Views with Parameters in more detail.
Next Post: SAP HANA ABAP Training. Part VI. New Age Open SQL ABAP 740
In this article, we would take a break from HANA. We would pause and check
what is available in Open SQL. Why is it called Open? You guessed it correct!!
Open means “Open to any Database“, i.e. database independent. You do not
need to have HANA database to take advantage of the Open SQL statements
which can improve the way we develop our applications.
If you have been following the previous posts on SAP ABAP on HANA, you
would know that CDS View is another technique to achieve Code to Data
paradigm. If the same functionality can be achieved by both CDS
Technique and Open SQL, which one should we adopt?
Answer: SAP wants us to stay Open. Open SQL is the first choice. Then
comes CDS View and then the stored procedures (ADBC, ADMP which we will
cover in our subsequent articles).
The whole idea of the modern ABAP/SQL/HANA is to push down logic to the
database. We outsource these powerful innovations to put and execute the logic
in the database. But do remember, SAP also wants to be as Open as
possible. So given a choice between database specific and database
independent solution, always chose the latter (database independent).
Enough of preaching, let us come to the topic of the day. New Age SQL for
ABAP.
We defined the TYPES. We looped through the table and added the custom logic
(High Purchase or Low Purchase) as shown below.
1
2 TYPES: BEGIN OF ty_ekpo,
3 ebeln TYPE ebeln,
4 ebelp TYPE ebelp,
5 werks TYPE ewerk,
6 netpr TYPE bprei,
7 pur_type TYPE char14,
8 END OF ty_ekpo.
9
10 DATA: it_ekpo TYPE STANDARD TABLE OF ty_ekpo.
11
12 FIELD-SYMBOLS <fs_ekpo> TYPE ty_ekpo.
13
14 SELECT ebeln ebelp werks netpr
15 FROM ekpo
16 INTO TABLE it_ekpo.
17
18 LOOP AT it_ekpo ASSIGNING <fs_ekpo>.
19
20 IF <fs_ekpo>-netpr GT 299.
21 <fs_ekpo>-pur_type = 'High Purchase'.
22 ELSE.
23 <fs_ekpo>-pur_type = 'Low Purchase'.
24 ENDIF.
25
26 ENDLOOP.
27
28 IF it_ekpo IS NOT INITIAL.
29 cl_demo_output=>display_data(
30 EXPORTING
31 value = it_ekpo
32 name = 'Old AGE SQL : 1' ).
33 ENDIF.
Let us see how we can achieve the same thing in a new way. With ABAP 740
and above, we get rid of TYPES, Data Declaration and Loop. Isn’t it cool?
1
2 SELECT ebeln, ebelp, werks, netpr,
3 CASE
4 WHEN netpr > 299
5 THEN 'High Purchase'
6 ELSE 'Low Purchase'
7 END AS pur_type
8 FROM ekpo
9 INTO TABLE @DATA(lt_sales_order_header).
10
11 IF sy-subrc = 0.
12 cl_demo_output=>display_data(
13 EXPORTING
14 value = lt_sales_order_header
15 name = 'New AGE SQL : 1' ).
16 ENDIF.
Outputs from both the above techniques are same. But the path does matters.
Isn’t it?
If you have some confusion regarding HANA, check this popular post: SAP
HANA from Space Level.
DISTINCT Material is 1 and DISTINCT Plant is 2. SUM for the Unrestricted stock
is 2, AVG is 2/2 = 1 and SUM of Blocked stock is 2. This is just a sample to
showcase how versatile and powerful the SELECT statement has become.
Next, in our menu, today is the Mathematical Operators in SELECT. Check the
below snippet where we can directly assign ’10’ (as rebate percent) which would
be in the internal table. CEIL function, multiplication, subtraction etc can be
handled during the SELECT statement. If we were not in 740, we would have
needed a separate loop and bunch of code to achieve this function. Isn’t ABAP
real modern now?
1
2 DATA: lv_rebate TYPE p DECIMALS 2 VALUE '0.10'.
3
4 SELECT ebeln,
5 10 AS rebate_per,
6 CEIL( netpr ) AS whole_ord_net,
7 ( @lv_rebate * netpr ) AS rebate,
8 ( netpr - ( @lv_rebate * netpr ) ) AS act_net
9 FROM ekpo
10 USING CLIENT '130'
11 UP TO 10 ROWS
12 INTO TABLE @DATA(lt_po_data).
13
14 IF sy-subrc = 0.
15 cl_demo_output=>display_data(
16 EXPORTING
17 value = lt_po_data
18 name = 'New AGE SQL : 3' ).
19 ENDIF.
Not only Mathematics is fun with ABAP 740, but also logical programming.
Continue below to taste the new flavour.
1
2 PARAMETERS: p_werks TYPE werks_d.
3 DATA:
4 lv_rebate TYPE p DECIMALS 2 VALUE '0.10',
5 lv_high_rebate TYPE p DECIMALS 2 VALUE '0.30'.
6
7 SELECT ebeln,
8 werks,
9 CEIL( netpr ) AS whole_ord_net,
10 ( @lv_rebate * netpr ) AS rebate,
11 ( netpr - ( @lv_rebate * netpr ) ) AS act_net,
12
13 CASE WHEN werks = @p_werks " For specific plant
14 THEN @lv_rebate
15 ELSE @lv_high_rebate
16 END AS rebate_type,
17
18 CASE WHEN werks = @p_werks " For specific plant
19 THEN 'low rebate'
20 ELSE 'high rebate'
21 END AS low_high
22
23 FROM ekpo
24 USING CLIENT '130'
25 UP TO 25 ROWS
26 INTO TABLE @DATA(lt_po_data).
27
28 IF sy-subrc = 0.
29 cl_demo_output=>display_data(
30 EXPORTING
31 value = lt_po_data
32 name = 'New AGE SQL : 4' ).
33 ENDIF.
34
35
COALESCE’s literal meaning from the dictionary is ‘come together and form
one mass or whole‘ or ‘combine (elements) in a mass or whole‘.
Check the usage below. If data for ekko~lifnr is present (means PO is created
for the lessor) then the LIFNR (Vendor Number) from EKKO is printed else, ‘No
PO’ literal is updated. This function is quite handy in many real practical
scenarios.
1
2 SELECT lfa1~lifnr,
3 lfa1~name1,
4 ekko~ebeln,
5 ekko~bukrs,
6 COALESCE( ekko~lifnr, 'No PO' ) AS vendor
7 FROM lfa1 AS lfa1 LEFT OUTER JOIN ekko AS ekko
8 ON lfa1~lifnr EQ ekko~lifnr
9 AND ekko~bukrs LT '0208'
10 INTO TABLE @DATA(lt_vend_po)
11 UP TO 100 ROWS.
12
13 IF sy-subrc = 0.
14 cl_demo_output=>display_data(
15 EXPORTING
16 value = lt_vend_po
17 name = 'New AGE SQL : 5' ).
18 ENDIF.
Also Read: Are you a Lazy ABAPer?
How many times and in how many projects did you have the requirement to
print Plant and Plant description together like 0101 (Houston Site) or in forms
you had the requirement to write Payee (Payee Name)? We achieved it by
looping and concatenating. We did not have better option earlier, but now we
can do it while selecting the data. Thanks to the SAP Development Team.
1
2 SELECT lifnr
3 && '(' && name1 && ')' AS Vendor,
4 ORT01 as city
5 FROM lfa1
6 INTO TABLE @DATA(lt_bp_data)
7 UP TO 100 ROWS.
8 IF sy-subrc = 0.
9 cl_demo_output=>display_data(
10 EXPORTING
11 value = lt_bp_data
12 name = 'New AGE SQL : 6' ).
13 ENDIF.
Every report/conversion/interface asks us to validate the input data and we do
it by checking its existence in the check table. That has become easier and
better now like shown below.
1
2 SELECT SINGLE @abap_true
3 FROM mara
4 INTO @DATA(lv_exists)
5 WHERE MTART = 'IBAU'.
6 IF lv_exists = abap_true.
7 WRITE:/ 'Data Exists!! New AGE SQL : 7'.
8 ENDIF.
ABAP was always a fifth generation programming language and it has become
more so. It has become more readable and real life syntactically too.
1
2 SELECT lfa1~lifnr,
3 lfa1~name1,
4 ekko~ebeln,
5 ekko~bukrs
6 FROM lfa1 AS lfa1 INNER JOIN ekko AS ekko
7 ON lfa1~lifnr EQ ekko~lifnr
8 AND ekko~bukrs LT '0208'
9 INTO TABLE @DATA(lt_vend_po)
10 GROUP BY lfa1~lifnr, lfa1~name1, ekko~ebeln, ekko~bukrs
11 HAVING lfa1~lifnr > '0000220000'.
12
13 IF sy-subrc = 0.
14 cl_demo_output=>display_data(
15 EXPORTING
16 value = lt_vend_po
17 name = 'New AGE SQL : 8' ).
18 ENDIF.
You might also enjoy GPS like Tool in SAP.
Remember, sometimes we need to select all fields of more than one table and
provide custom names in the output. Wasn’t it tiresome to create TYPEs and
achieve our requirement?
1
2 SELECT jcds~*,
3 tj02t~*
4 FROM jcds INNER JOIN tj02t
5 ON jcds~stat = tj02t~istat
6 WHERE tj02t~spras = @sy-langu
7 INTO TABLE @DATA(lt_status)
8 UP TO 1000 ROWS.
9 IF sy-subrc = 0.
10 cl_demo_output=>display_data(
11 EXPORTING
12 value = lt_status
13 name = 'New AGE SQL : 9' ).
14 ENDIF.
The above code is syntactically correct. Wow!! I was so excited to test it as it
would show all columns from both the tables.
Let us modify the same code a little bit. We need to define the TYPEs and
declare the internal table (Inline did not work above).
1
2 TYPES BEGIN OF ty_data.
3 INCLUDE TYPE jcds AS status_change RENAMING WITH SUFFIX _change.
4 INCLUDE TYPE tj02t AS status_text RENAMING WITH SUFFIX _text.
5 TYPES END OF ty_data.
6
7 DATA: lt_status TYPE STANDARD TABLE OF ty_data.
8 SELECT jcds~*,
9 tj02t~*
10 FROM jcds INNER JOIN tj02t
11 ON jcds~stat = tj02t~istat
12 WHERE tj02t~spras = @sy-langu
13 INTO TABLE @lt_status
14 UP TO 100 ROWS.
15
16 IF sy-subrc = 0.
17 cl_demo_output=>display_data(
18 EXPORTING
19 value = lt_status
20 name = 'New AGE SQL : 9' ).
21 ENDIF.
Check _CHANGE is added to the field name. _TEXT is also added in the column
name from second table (not captured in the screen print below)
These were just the tip of the icebergs. We would stumble upon more features
and surprises as we work on projects in real system. Just to let you know, all
the above code snippets are from a traditional database (not HANA) which
has EhP 7.4. So do not confuse that we need HANA database to take advantage
of modern SQL techniques. We just need near and above EhP 7.4.
Next Post: SAP HANA ABAP Tutorial. Part VII. SQL Script and SAP HANA Stored
Procedure
Update 08/25/2016:
We asked If CDS Views and SQL can achieve the same functionality.
Which one should we choose?
If there is a learning curve then go for the more widely known SQL and train the
development team for the next update, rather than putting in code that they
are either unhappy with or have little knowledge on.
At the end of the day, I would say use whichever one works best for your
project, team and application. The user should not see any difference in
usability. It is all about maintenance and knowledge at the end of the day.
If you want to get such useful articles directly to your inbox,
please SUBSCRIBE. We respect your privacy and take protecting it seriously.
In the previous post (New Age SQL for ABAP), we explored the modern SQL
which helps to push the code to the database and helps us with performance
improvement. Also, the new age SQL is concise and allows us to do kinds of
stuff which were never possible in ABAP earlier. In this article, we would
check SQL Script and basic about Stored Procedures.
SAP HANA SQL document says: SQL Script is a collection of extensions to the
Structured Query Language (SQL).
SAP further simplifies, SQL Script is and extension to ANSI Standard SQL. It
is an interface for applications to access SAP HANA database. SQL Script is the
language which can be used for the creation of stored procedures in HANA.
Data transfer between database and application layer can be eliminated using
SQL Script. Calculations can be executed in the database layer using SQL Script
to obtain maximum benefit out of SAP HANA database. It provides fast column
operations, query optimization and parallel execution (you will read these lines
time and again in different language in this post).
Motivation?
SQL Script can be utilized to write data-intensive logic into the database instead
of writing code in the application server. Before ABAP 740, most of the data
needed for manipulation were copied from database to the application server
and all calculation, filtration and other logic were implemented on these data.
This technique is a strict No-No for optimization and performance improvement
of the ABAP code. SQL Script helps to take maximum benefit of modern
hardware and software innovation to perform massive parallelization on multi-
core CPUs.
SAP suggests, SQL Script comes into picture when HANA modeling constructs
like Analytic or Attribute views fail. Someone’s failure is other one’s success.
Why?
Data transfer between database and application layer can be eliminated using
SQL Script. Calculations can be executed in the database layer using SQL Script
to obtain maximum benefit out of SAP HANA database. It provides fast column
operations, query optimization and parallel execution (you will read these lines
time and again in different languages in this post).
What is SQL Script? Why we need SQL Script? What is the motivation
for having SQL Script?
Did we not answer these What, Why and What above? OK, let’s start from the
beginning. The relational database model RDBMS was introduced back in
1970’s by Edger F. Codd(you might remember from college curriculum.
something ringing? or did I help you remember one of your beautiful/cute
crushes from your college days).
A simple example would be splitting of data into Header and Item to pass the
ACID test. In other words, data is stored in two-dimensional tables with the
foreign key relationship instead of having redundant rows and columns in one
table.
You can read more about Normalization here.
But the use of digital media has exploded in the recent past both in the
consumer world and enterprise world (in a way both are the same thing). This
has led to an exponential increase in the amount of the data being stored in the
databases. On the other hand, the expectation from users is minimum
response time, in some cases zero response time.
We can take the example of TATKAL IRCTC online train ticket booking. There
will be few Hundred Thousand if not Million users who want to book a Tatkal
ticket and expectation is there should not be any delay from the system. 2
Hundred Thousand transactions (form fill up, validation, payment using
credit/debit card or online banking) per minute was one of the criteria for the
vendor for IRCTC quote.
For our readers who are outside India, TATKAL’s literal English translation
is “INSTANT”. You can consider TATKAL train booking as the Amazon Black
Friday Sale of iPhone 6S at 99$. The sale begins exactly at 10:00 AM on
11/24/2016 till stock last. Isn’t iPhone 6S at 99$ an amazing deal? Even if you
already have iPhonse 6S, you would still try to buy it. Exactly at 10:00 AM,
thousands of users try to order that phone. Most users cannot log in,
the system is hung. Some lucky who are able to log in, are not able to hit BUY
button. Few others who were successful at hitting the BUY button are
still waiting for Payment to be entered. Few lucky who have successfully
entered the Payment get the final message, “Sorry, iPhone 6S is out of stock.
Please try later“.
HANA is able to deliver this. Absolutely no response lag time by using the
techniques which are both hardware and software innovation. Hence it is called
as Appliance and not just any Database. This is a separate topic altogether
which we have covered in “SAP HANA from Space Level“.
Now, if we want to use the power of fast computing of HANA Database, we have
to push all the data intensive computations from application server (ABAP
Server) to HANA Database layer. Here SQL Script plays the major part in doing
this.
Like any SQL language, SQL Script is used for querying the Database, in this
case, HANA Database. SQL Script is as per SQL 92 Standards. This is the sole
language used for writing Stored Procedures in the HANA Database.
i) Normal SQL returns only one result set while SQL Script can return multiple
results.
iii) Local variables for the transitional result can be defined in SQL Script.
Normal SQL needs globally visible data types/views for intermediate logic.
iv) Control statements like IF/ELSE are available in SQL Script but not in normal
SQL
SQL Script follows the Code to Data Paradigm with pushing of data intensive
computations to HANA Database. With this, it eliminates the transfer of data
from DB to the application server aka ABAP AS. This fully exploits the capability
of HANA database achieving themaximum throughput with absolutely no
response time.
SQL Script is a very powerful tool. We have always avoided using joins, ordering
by clause in ABAP SQL statements. All these are welcome in ABAP 740. We can
also use query inside a query etc.
1
2 create column table "<Schema_name>"."ZZSTUDENT"( "ROLLNUMBER" NVARCHAR (10) not
3 null,
4 "NAME" NVARCHAR (10) ,
"YEAR" NVARCHAR (4) );
Our schema name was SYSTEM. So, out SQL looks like below.
1
2 create column table "SYSTEM"."ZZSTUDENT"( "ROLLNUMBER" NVARCHAR (10) not
3 null,
4 "NAME" NVARCHAR (10) ,
"YEAR" NVARCHAR (4) );
Hopefully, you know by now that you need to be in SAP HANA Development
Perspective and choose your schema and write at the SQL Console. When
you hit execute, the table is created.
For GUI Click on New Table and for SQL Script above Click on Open SQL Console
Both (SQL and GUI) achieve the same function of creating the table
The tables that are created will be available in the respective Schema.
1
2 CREATE COLUMN TABLE "<SCHEMA_NAME>"."ZZENROLL"( "CODE" NVARCHAR (10) NOT
3 NULL,
4 "ROLLNUMBER" NVARCHAR (10) NOT NULL,
5 "YEAR" NVARCHAR (4) );
6
7 CREATE COLUMN TABLE "<SCHEMA_NAME>"."ZZCOURSE"( "CODE" NVARCHAR (10) NOT
NULL,
"NAME" NVARCHAR (10));
1
2 CREATE TYPE "<SCHEMA_NAME>"."LT_OUT" AS TABLE ( "STUDENT_NAME" VARCHAR (10) NOT
3 NULL,
4 "COURSE_CODE" VARCHAR (10),
"COURSE" VARCHAR (10));
1
2 ALTER TABLE "<SCHEMA_NAME>"."ZZSTUDENT" ALTER ("CITY" VARCHAR (30)
NULL);
1
2 ALTER TABLE "<SCHEMA_NAME>"."ZZSTUDENT" ALTER TYPE
ROW;
Data can be inserted using SQL Console. Below are some examples:
1
2 INSERT INTO "<SCHEMA_NAME>"."ZZSTUDENT" VALUES ( '10', 'SACHIN',
'MUMBAI');
1
2 INSERT INTO "<SCHEMA_NAME>"."ZZCOURSE" VALUES('100','HINDI');
3 INSERT INTO "<SCHEMA_NAME>"."ZZCOURSE"
4 VALUES('200','ENGLISH');
INSERT INTO "<SCHEMA_NAME>"."ZZCOURSE" VALUES('300','MATHS');
1
2 INSERT INTO "<SCHEMA_NAME>"."ZZENROLL" VALUES ( '100', '10',
3 '2005');
4 INSERT INTO "<SCHEMA_NAME>"."ZZENROLL" VALUES ( '200', '10',
'2005');
INSERT INTO "<SCHEMA_NAME>"."ZZENROLL" VALUES ( '300', '10',
'2005');
Lets us see some of the SQL Query Examples on the above data which we have
populated.
1
2 SELECT NAME
3 FROM "<SCHEMA_NAME>"."ZZSTUDENT"
4 WHERE ROLLNUMBER = '10';
b) Nested Select or Select inside a Select (name of students who have enrolled
for course code 100)
1
2 SELECT NAME
3 FROM "<SCHEMA_NAME>"."ZZSTUDENT"
4 WHERE ROLLNUMBER IN (SELECT ROLLNUMBER
5 FROM "<SCHEMA_NAME>"."ZZENROLL"
6 WHERE CODE = '100');
c) A join example
1
2 SELECT A.NAME AS STUDENT_NAME,
3 B.CODE AS COURSE_CODE,
4 C.NAME AS COURSE
5 FROM "<SCHEMA_NAME>"."ZZSTUDENT" AS A
6 INNER JOIN "<SCHEMA_NAME>"."ZZENROLL" AS B
7 ON A.ROLLNUMBER = B.ROLLNUMBER
8 INNER JOIN "<SCHEMA_NAME>"."ZZCOURSE" AS C
9 ON B.CODE = C.CODE
10 WHERE C.CODE = '100';
These are very basic examples, only for the concept. In real time it would not
be this simple. Hope the above examples give you a hang of SQLScript. It might
be a little different for ABAPers but it is not entirely from another planet. We
have been writing Open SQL in ABAP and the above SQL Scripts are our nearest
cousins. Nothing to be scared of.
Stored Procedure
Stored Procedure is the natural choice for the next topic as SQL Script is the
only language used for creating Stored Procedures. A procedure is a unit/block
of related code that performs a certain task. ABAPers can relate Stored
Procedures as the subroutines or methods (not truly though). The motivation
for having the procedure is reusability.
All the advantages of SQL Scripts are there in Stored Procedures. SAP
HANA procedures help us to put data-intensive complex logic into the database,
where it can be fine tuned and optimized for performance and return the small
result set. Procedures help to control the network and processor load by not
transferring large data volume from database layer to application layer. Stored
Procedures can return multiple scalar (single value), tabular/array result which
is not possible in normal SQL. Like in ABAP programming, local variables can be
declared and used in Procedures and hence we do not need to create temporary
tables to be used for storing intermediate data as in the case of normal SQL.
General rule
One can create Stored Procedure with the help of GUI. This is much faster
and one tends to have less number of human error.
Create the output parameters: Right click on Output, Input Parameters and
declare the name and types.
Click on save and validate
Click on activate
To test the procedure created above, we need to call the procedure in the SQL
Console. Generic syntax for calling procedure is below.
1
2 CALL PROCEDURE_NAME (values1, values2 ,......);
1
2 CALL ZZPROCEDURE(100,?)
Food for thought: Check what error we get if we just write below SQL without
“?” as second parameter.
1
2 CALL ZZPROCEDURE(100)
We have created a procedure in HANA Database. Till now, only the half part is
done. If we want to achieve the Code Push Down Paradigm then the next part
would be calling the procedure in SAP ECC. This is achieved using Database
Procedure Proxy.
Go to File -> New -> Others -> Database Procedure Proxy.
Click on finish
Click on Activate button as shown below
The same Database Procedure Proxy can be displayed in SE24 at ABAP AS level.
Calling this Database proxy is very much similar to calling a function
module/method.
1
2 CALL DATABASE PROCEDURE ZZ12MYDBPROXY
3 EXPORTING iv_code = p_code
4 IMPORTING lt_out = tb_output.
1
2 **---------------------------------------------------------------------*
3 ** TYPES *
4 **---------------------------------------------------------------------*
5 TYPES:
6
7 BEGIN OF ty_output,
8 student_name TYPE char10,
9 course_code TYPE char10,
10 course TYPE char10,
11 END OF ty_output.
12
13 **---------------------------------------------------------------------*
14 ** DATA *
15 **---------------------------------------------------------------------*
16 DATA:
17 it_output TYPE TABLE OF ty_output.
18
19 **---------------------------------------------------------------------*
20 ** SELECTION SCREEN *
21 **---------------------------------------------------------------------*
22 SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-s01.
23 PARAMETERS: p_code TYPE char10.
24 SELECTION-SCREEN END OF BLOCK b1.
25
26 **---------------------------------------------------------------------*
27 ** START-OF-SELECTION. *
28 **---------------------------------------------------------------------*
29 START-OF-SELECTION.
30 * Consume the stored procedure in ABAP
31 PERFORM call_db_procedure.
32
33 **---------------------------------------------------------------------*
34 ** END-OF-SELECTION. *
35 **---------------------------------------------------------------------*
36 END-OF-SELECTION.
37 * Display the output
38 PERFORM display_output.
39
40 **&---------------------------------------------------------------------*
41 **& SUB ROUTINES
42 **&---------------------------------------------------------------------*
43
44 *&---------------------------------------------------------------------*
45 *& Form CALL_DB_PROCEDURE
46 *&---------------------------------------------------------------------*
47 * Consume the database procedure
48 *----------------------------------------------------------------------*
49 FORM call_db_procedure.
50
51 * Callling Database Procedure
52 CALL DATABASE PROCEDURE zz12mydbproxy
53 EXPORTING
54 iv_code = p_code
55 IMPORTING
56 lt_output = it_output.
57
58 ENDFORM.
59
60 *&---------------------------------------------------------------------*
61 *& Form DISPLAY_OUTPUT
62 *&---------------------------------------------------------------------*
63 * Display the Report
64 *----------------------------------------------------------------------*
65 FORM display_output .
66
67 * Display the output
68 cl_demo_output=>display_data( it_output ).
69
70 ENDFORM.
Output
We showed Database Proxy is one way to consume Stored Procedure in
ABAP. The other way is calling it through Native SQL. Let us extend this long
post a little longer. This is the last part, trust me.
ii) Using Database Procedure Proxy to expose HANA Procedure (already seen
above)
Both has pros and cons, but Database proxy has an upper hand over the native
SQL.
a) Easy development and lesser effort. Once we have the stored procedure
created in the HANA DB, we just need to write native SQL to access the
procedure directly.
b) No extra ABAP artifact means less maintenance. Since there is no other ABAP
artifact to be created (like Database Proxy), less maintenance in this case
c) Native SQL Development can be done in SAP GUI as well as ADT, whereas for
DB proxy has to be done via ADT only
b) Full advantage of ABAP Development Tool can be taken for Database Proxy.
c) ABAP developers would find Database Procedure Proxy call similar to Function
Module/Method calls. Hence more comfortable.
d) In the case of any change in Database Procedure the code changing process
is manual. But for proxy it is semi-manual and the proxy can be synchronized
(merged/deleted).
We have just scratched the surface. We need to dig a little more deeper to
appreciate the power of SQL Script and Store Procedures. We can have a
separate post in detail on consumption of Stored Procedures in ABAP. Also, we
can check how we can debug the procedures.
ABAP on SAP HANA. Part VIII. ADBC
– ABAP DataBase Connectivity
about Database Connectivity. Although the title says, SAP ABAP for HANA, but
let me clarify, ADBC (ABAP DataBase Connectivity) is not the proprietary
feature of HANA. This property is database independent. Years ago even before
we heard about HANA, ABAPer used to connect to underlying database explicitly
using native SQL and perform the needful activity. If you have ever had the
opportunity to work in that area, then you would remember how you used
something like below code snippet (with or without knowing what you were
doing).
1
2 EXEC SQL.
3 <Native SQL statements to perform the requirement>
4 ENDEXEC.
. The most generic reason why Native SQL was used is, the database tables
were not available in SAP Data Dictionary. Yes, you read it right. There are
numerous tables in the database, which do not find the dignity of residing at
both places (database and SAP Data Dictionary). And business might be using
those database specific tables for some business case. In such cases, native
SQL used to be the life saver.
3. The data is transported between the database table and the ABAP program
using host variables. Host variables? Forget it. It is the same work areas and
variables (line in open SQL) which have additional “:’ (colon) in front.
1
2 EXEC SQL.
3 SELECT matnr mtart bismt
4 INTO :wa_mara
5 FROM mara
6 WHERE matnr = :p_matnr
7 ENDEXEC.
The above example does not justify the usage of native SQL, as MARA should
reside at both places. Just replace MARA with something like ORA_INV_MGT
table which is not available in SE11.
So, in the above example concentrate on : P_MATNR and : WA_MARA (the host
variables).
1. Open SQL provides a uniform syntax and semantics for all of the database
systems supported by SAP. Therefore it is called Open. Open to all Database.
ABAP Programs that only use Open SQL statements will work in any SAP
system, regardless of the below database system.
2. Open SQL statements can only work for database tables that have been
created/replicated in the ABAP Dictionary
I think we have built up enough background and refresher to finally come to the
topic of the day, i.e. ADBC. If native SQL was already doing what Open SQL
could not do, then what was the need of introducing another jargon ADBC.
Sometimes if you make something look complex, people tend to think it
superior and better.
But ADBC is not just another bombastic word. It is definitely better than native
SQL as explained below.
ADBC is an object base API. This API determines where native SQL calls have
been madeand supports exception handling better. Technically, ADBC writes
native SQL which would be executed at the database layer. But, ADBC makes
the process of connecting to the database and transferring the native SQL code
to be executed at database layer smoother and organized. In simple terms,
the object-oriented approach is used by ADBC to connect to the database and
perform the needed task.
Object Oriented approach bring with it flexibility and ADBC is found in WHERE
USED LIST and also error handling of the same native SQL code is better in
ADBC.
1. Just like native SQL, syntax checker cannot catch issues in the code which
the underlying database is expecting. We need to handle the exceptions
properly (usually cx_sql_exception is implemented).
2. Hashed and Sorted tables are not allowed as the target. So, the standard
table is still the king.
3. If you are using ADBC, do not forget to handle the client/mandt explicitly in
your code.
4. ADBC does not necessarily release the allocated memory/resource on the DB.
As a good practice, we should always close the query.
We have been singing Object Oriented Approach for quite some time in this
article, so some of the classes and methods do need a mention here. What do
you guys say?
. The above 8 steps help us narrow down to three important classes in ADBC.
1. CL_SQL_CONNECTION
2. CL_SQL_STATEMENT
3. CL_SQL_RESULT_SET
Below code shows the usage of ADBC in ABAP which has HANA as the database.
The most important part is building the native SQL correctly (using string
operations or CONCATENATE statement) as per the database and passing it in
the string.
If you are in HANA, it is a good practice to test the native SQL in SQL editor at
HANA Studio.
Also Read: Know about SAP HANA Studio icons and buttons
If the database is not HANA and you do not have SQL editor (HANA studio) do
not be disheartened. You can still check the native SQL at DBACOCKPIT. It is
shown a little below in this article.
For HANA Database user, your first ADBC program is below. The ADBC API in
the program is self-explanatory and easy to implement. So, EXEC SQL –
ENDEXEC would definitely be the thing of the past. This program is for those
lucky ones who are already in HANA database. Others can scroll down below to
find the program for the non-HANA system. This program would not return any
result if you are not in HANA, as the native SQL is dependent on the database.
The native SQL written below is compatible with HANA only.
1
2 * Type for output
3 TYPES: BEGIN OF ty_result,
4 matnr TYPE matnr,
5 mtart TYPE mtart,
6 maktx TYPE maktx,
7 END OF ty_result.
8
9 * Data declaration
10 DATA: lr_sql_connection TYPE REF TO cl_sql_connection,
11 lr_sql_statement TYPE REF TO cl_sql_statement,
12 lr_sql_result_set TYPE REF TO cl_sql_result_set,
13 lr_sql_exception TYPE REF TO cx_sql_exception,
14 lr_sql_parameter_invalid TYPE REF TO cx_parameter_invalid,
15 lr_parameter_invalid_type TYPE REF TO cx_parameter_invalid_type,
16 lr_salv_exception TYPE REF TO cx_salv_msg,
17 lr_salv_alv TYPE REF TO cl_salv_table,
18 lt_result TYPE STANDARD TABLE OF ty_result,
19 ls_result TYPE ty_result,
20 lr_data TYPE REF TO data,
21 lv_where_clause_statement TYPE string,
22 lv_error_text TYPE string,
23 lv_where_mandt TYPE string,
24 lv_where_spras TYPE string.
25 * Selection screen fields
26 SELECT-OPTIONS : s_matnr FOR ls_result-matnr,
27 s_mtart FOR ls_result-mtart.
28
29 * Connect to dabatabse (HANA or Non-HANA)
30 * 1 Set the database connection
31 PERFORM make_db_connection.
32
33 * Instantiate SQL Statement
34 * i.e Get the SQL Statement reference using the instance of the connection
35 * 2. Instantiate the statement object
36 PERFORM ini_sql_statement.
37
38 * Prepare Native SQL statements
39 * 3. Construct the SQL using Concatenate syntax or string operation
40 PERFORM prepare_native_sql_string.
41
42 * Using the reference of the statement call, the respective methods to execute the query
43 * 4. Issue Native SQL Call
44 PERFORM issue_native_sql_call.
45
46 * Get the result of the query in a table
47 * 5. Assign Target variable for result set
48 PERFORM assign_target_result.
49
50 * 6. Retrieve Result set
51 PERFORM retrieve_complete_result_set.
52
53 * 7. Close the query, release resource
54 PERFORM close_query.
55
56 * 8. Close DB Connection
57 PERFORM close_db_connection.
58
59 * 9. Display output
60 PERFORM display_result.
61 **&---------------------------------------------------------------------*
62 **& Sub Routines
63 **&---------------------------------------------------------------------*
64 *&---------------------------------------------------------------------*
65 *& Form MAKE_DB_CONNECTION
66 *&---------------------------------------------------------------------*
67 * Connect to database
68 *----------------------------------------------------------------------*
69 FORM make_db_connection .
70
71 TRY.
72 * Get the DB (HANA/Non HANA) Connection
73 * If we do not pass the DB name, it would pull the default database
74 lr_sql_connection ?= cl_sql_connection=>get_connection( ).
75
76 * 10. Catch errors/exceptions (if any)
77 CATCH cx_parameter_invalid_type INTO lr_parameter_invalid_type.
78 lv_error_text = lr_parameter_invalid_type->get_text( ).
79 MESSAGE e000 WITH lv_error_text.
80
81 CATCH cx_parameter_invalid INTO lr_sql_parameter_invalid.
82 lv_error_text = lr_sql_parameter_invalid->get_text( ).
83 MESSAGE e001 WITH lv_error_text.
84
85 CATCH cx_sql_exception INTO lr_sql_exception.
86 lv_error_text = lr_sql_exception->get_text( ).
87 MESSAGE e001 WITH lv_error_text.
88
89 CATCH cx_salv_msg INTO lr_salv_exception.
90 lv_error_text = lr_salv_exception->get_text( ).
91 MESSAGE e001 WITH lv_error_text.
92
93 ENDTRY.
94
95 ENDFORM.
96 *&---------------------------------------------------------------------*
97 *& Form INI_SQL_STATEMENT
98 *&---------------------------------------------------------------------*
99 * Instantiate the statement object
100 *----------------------------------------------------------------------*
101 FORM ini_sql_statement .
102 IF lr_sql_connection IS BOUND.
103
104 TRY.
105
106 * Get the SQL Statement reference using the instance of the connection
107 CREATE OBJECT lr_sql_statement
108 EXPORTING
109 con_ref = lr_sql_connection. " Database Connection
110
111 * 10. Catch errors/exceptions (if any)
112 CATCH cx_parameter_invalid_type INTO lr_parameter_invalid_type.
113 lv_error_text = lr_parameter_invalid_type->get_text( ).
114 MESSAGE e000 WITH lv_error_text.
115
116 CATCH cx_parameter_invalid INTO lr_sql_parameter_invalid.
117 lv_error_text = lr_sql_parameter_invalid->get_text( ).
118 MESSAGE e001 WITH lv_error_text.
119
120 CATCH cx_sql_exception INTO lr_sql_exception.
121 lv_error_text = lr_sql_exception->get_text( ).
122 MESSAGE e001 WITH lv_error_text.
123
124 CATCH cx_salv_msg INTO lr_salv_exception.
125 lv_error_text = lr_salv_exception->get_text( ).
126 MESSAGE e001 WITH lv_error_text.
127
128 ENDTRY.
129
130 IF lr_sql_connection IS NOT BOUND.
131 MESSAGE 'No reference to SQL Statements made' TYPE 'I'.
132 LEAVE LIST-PROCESSING.
133 ENDIF.
134
135 ELSE.
136 MESSAGE 'No connection established' TYPE 'I'.
137 LEAVE LIST-PROCESSING.
138 ENDIF.
139 ENDFORM.
140 *&---------------------------------------------------------------------*
141 *& Form PREPARE_NATIVE_SQL_STRING
142 *&---------------------------------------------------------------------*
143 * Construct the SQL using Concatenate syntax or string operation
144 *----------------------------------------------------------------------*
145 FORM prepare_native_sql_string .
146
147 * In line data declaration and converting selection option to a where clause string for S_MATNR
148 DATA(lr_seltab) = cl_lib_seltab=>new( it_sel = s_matnr[] ).
149 DATA(lv_where_clause_sel) = lr_seltab->sql_where_condition( iv_field = 'M.MATNR' ).
150
151 * In line data declaration and converting selection option to a where clause string for S_MTART
152 DATA(lr_seltab2) = cl_lib_seltab=>new( it_sel = s_mtart[] ).
153 DATA(lv_where_clause_sel2) = lr_seltab2->sql_where_condition( iv_field = 'M.MTART' ).
154
155 *--------------------------------------------------------------------*
156 * Begin of script for HANA Database
157 *--------------------------------------------------------------------*
158 * Construct the SQL in SQL Console Eclipse and put it in a string ( Native SQL Only )
159 * Modern sysntax for concatenation
160 lv_where_clause_statement = | SELECT M.MATNR, M.MTART, T.MAKTX |
161 && | FROM MARA AS M INNER JOIN MAKT AS T |
162 && | ON M.MATNR = T.MATNR |
163 && | WHERE M.MANDT = '{ sy-mandt }' |
164 && | AND T.SPRAS = '{ sy-langu }' |
165 && | AND { lv_where_clause_sel } |
166 && | AND { lv_where_clause_sel2 } |
167 && | ORDER BY M.MATNR |.
168 *--------------------------------------------------------------------*
169 * End of script for HANA Database
170 *--------------------------------------------------------------------*
171
172 ** Modern sysntax for Concatenation
173 * lv_where_mandt = |'| && |{ sy-mandt }| && |'|.
174 * lv_where_spras = |'| && |{ sy-langu }| && |'|.
175 *
176 * lv_where_mandt = |M.MANDT = | && | { lv_where_mandt }|.
177 * lv_where_spras = |T.SPRAS = | && | { lv_where_spras }|.
178 *
179 **--------------------------------------------------------------------*
180 ** Begin of script for ORACLE Database
181 **--------------------------------------------------------------------*
182 ** Construct the SQL in SQL Console Eclipse and put it in a string ( Native SQL Only )
183 * lv_where_clause_statement = | SELECT M.MATNR, M.MTART, T.MAKTX |
184 * && | FROM MARA M, MAKT T |
185 * && | WHERE M.MATNR = T.MATNR |
186 * && | AND { lv_where_mandt } |
187 * && | AND { lv_where_spras } |
188 * && | AND { lv_where_clause_sel } |
189 * && | AND { lv_where_clause_sel2 } |.
190 **--------------------------------------------------------------------*
191 ** End of script for ORACLE Database
192 **--------------------------------------------------------------------*
193
194 * If you find difficulty in understanding above concatenate/string operation,
195 * Then check below. It does the same thing as above.
196 * CONCATENATE '''' sy-mandt '''' INTO lv_where_mandt.
197 * CONCATENATE '''' sy-langu '''' INTO lv_where_spras.
198 *
199 * CONCATENATE 'M.MANDT = ' lv_where_mandt INTO lv_where_mandt SEPARATED BY space.
200 * CONCATENATE 'T.SPRAS = ' lv_where_spras INTO lv_where_spras SEPARATED BY space.
201 *
202 * construct the sql in sql command editor in dbacockpit
203 * below sql works for oracle database
204 * concatenate 'SELECT M.MATNR, M.MTART, T.MAKTX'
205 * 'FROM MARA M, MAKT T'
206 * 'WHERE M.MATNR = T.MATNR'
207 * 'AND' lv_where_mandt
208 * 'AND' lv_where_spras
209 * 'and' lv_where_clause_sel
210 * 'and' lv_where_clause_sel2
211 * into lv_where_clause_statement separated by space.
212
213 ENDFORM.
214 *&---------------------------------------------------------------------*
215 *& Form ISSUE_NATIVE_SQL_CALL
216 *&---------------------------------------------------------------------*
217 * Issue Native SQL Call
218 *----------------------------------------------------------------------*
219 FORM issue_native_sql_call .
220
221 TRY.
222
223 * Using the reference of the statement call the respective methods to execute the query
224 lr_sql_statement->execute_query(
225 EXPORTING
226 statement = lv_where_clause_statement " SELECT Statement Being Executed
227 hold_cursor = space
228 RECEIVING
229 result_set = lr_sql_result_set ). " Database Cursor
230
231 * 10. Catch errors/exceptions (if any)
232 CATCH cx_parameter_invalid_type INTO lr_parameter_invalid_type.
233 lv_error_text = lr_parameter_invalid_type->get_text( ).
234 MESSAGE e000 WITH lv_error_text.
235
236 CATCH cx_parameter_invalid INTO lr_sql_parameter_invalid.
237 lv_error_text = lr_sql_parameter_invalid->get_text( ).
238 MESSAGE e001 WITH lv_error_text.
239
240 CATCH cx_sql_exception INTO lr_sql_exception.
241 lv_error_text = lr_sql_exception->get_text( ).
242 MESSAGE e001 WITH lv_error_text.
243
244 CATCH cx_salv_msg INTO lr_salv_exception.
245 lv_error_text = lr_salv_exception->get_text( ).
246 MESSAGE e001 WITH lv_error_text.
247
248 ENDTRY.
249
250 ENDFORM.
251 *&---------------------------------------------------------------------*
252 *& Form ASSIGN_TARGET_RESULT
253 *&---------------------------------------------------------------------*
254 * Assign Target variable for result set
255 *----------------------------------------------------------------------*
256 FORM assign_target_result .
257
258 TRY.
259
260 * Get the result of the query in a table
261 GET REFERENCE OF lt_result INTO lr_data.
262 lr_sql_result_set->set_param_table(
263 EXPORTING
264 itab_ref = lr_data ). " Reference to Output Variable
265
266 * 10. Catch errors/exceptions (if any)
267 CATCH cx_parameter_invalid_type INTO lr_parameter_invalid_type.
268 lv_error_text = lr_parameter_invalid_type->get_text( ).
269 MESSAGE e000 WITH lv_error_text.
270
271 CATCH cx_parameter_invalid INTO lr_sql_parameter_invalid.
272 lv_error_text = lr_sql_parameter_invalid->get_text( ).
273 MESSAGE e001 WITH lv_error_text.
274
275 CATCH cx_sql_exception INTO lr_sql_exception.
276 lv_error_text = lr_sql_exception->get_text( ).
277 MESSAGE e001 WITH lv_error_text.
278
279 CATCH cx_salv_msg INTO lr_salv_exception.
280 lv_error_text = lr_salv_exception->get_text( ).
281 MESSAGE e001 WITH lv_error_text.
282
283 ENDTRY.
284 ENDFORM.
285 *&---------------------------------------------------------------------*
286 *& Form RETRIEVE_COMPLETE_RESULT_SET
287 *&---------------------------------------------------------------------*
288 * Retrieve Result set
289 *----------------------------------------------------------------------*
290 FORM retrieve_complete_result_set .
291
292 TRY.
293
294 lr_sql_result_set->next_package( ).
295
296 CATCH cx_parameter_invalid_type INTO lr_parameter_invalid_type.
297 lv_error_text = lr_parameter_invalid_type->get_text( ).
298 MESSAGE e000 WITH lv_error_text.
299
300 CATCH cx_parameter_invalid INTO lr_sql_parameter_invalid.
301 lv_error_text = lr_sql_parameter_invalid->get_text( ).
302 MESSAGE e001 WITH lv_error_text.
303
304 CATCH cx_sql_exception INTO lr_sql_exception.
305 lv_error_text = lr_sql_exception->get_text( ).
306 MESSAGE e001 WITH lv_error_text.
307
308 CATCH cx_salv_msg INTO lr_salv_exception.
309 lv_error_text = lr_salv_exception->get_text( ).
310 MESSAGE e001 WITH lv_error_text.
311
312 ENDTRY.
313
314 ENDFORM.
315 *&---------------------------------------------------------------------*
316 *& Form CLOSE_QUERY
317 *&---------------------------------------------------------------------*
318 * Close the query, release resources
319 *----------------------------------------------------------------------*
320 FORM close_query .
321
322 lr_sql_result_set->close( ).
323
324 ENDFORM.
325 *&---------------------------------------------------------------------*
326 *& Form CLOSE_DB_CONNECTION
327 *&---------------------------------------------------------------------*
328 * Close DB connection
329 *----------------------------------------------------------------------*
330 FORM close_db_connection .
331
332 lr_sql_connection->close( ).
333
334 ENDFORM.
335 *&---------------------------------------------------------------------*
336 *& Form DISPLAY_RESULT
337 *&---------------------------------------------------------------------*
338 * Display ALV
339 *----------------------------------------------------------------------*
340 FORM display_result .
341
342 * Display the data in an ALV
343 cl_salv_table=>factory(
344 IMPORTING
345 r_salv_table = lr_salv_alv " Basic Class Simple ALV Tables
346 CHANGING
347 t_table = lt_result ).
348
349 * Show the output
350 lr_salv_alv->display( ).
351
352 ENDFORM.
*——————————————————————–*
*——————————————————————–*
*——————————————————————–*
*——————————————————————–*
And uncomment the tags in between the below two tags for ORACLE database.
*——————————————————————–*
*——————————————————————–*
*——————————————————————–*
*——————————————————————–*
If the native SQL is not prepared correctly, we get errors like show here.
Let us check the output for the same program with ORACLE database users.
DBACOCKPIT
If you are in HANA database, you can easily check the syntax of native SQL in
SQL editor at HANA Studio. But if you do not have HANA database, you can
check the native SQL of your database using t-code DBACOCKPIT. Just follow
the path shown in below image. Execute or hit F8 and if there is any issue in the
SQL, you can easily find them in the error/message log window at the bottom.
Check the native SQL for ORACLE database. The JOIN statement for ORACLE is
different. There is no explicit JOIN command. Two tables to be joined are
separated by comma.
. I had to waste few hours just to figure this out (as I have no ORACLE SQL
experience) :). Also, check fields selected are separated by comma and there is
no Tilda (as in open SQL joins).
Have questions about HANA? Check SAP HANA from Space Level.
1. If a table resides both at Data Dictionary and Database. Does it make sense
to use native SQL and/or ADBC so that the table is encountered at the database
level itself?
Answer: SAP/HANA experts say that if the table resides both at database and
SAP data dictionary, Open SQL should always be the first choice. Open SQL is
optimized for communication with the database. If someone tries to be
adventurous by using native SQL or ADBC when it is not needed, then it might
worsen the performance because of overhead (like connection, constructor calls,
statement class, query etc) in the ADBC framework.
2. If a table resides only in the Database, what should be used? Native SQL by
using EXEC SQL – ENDEXEC or by calling ADBC?
Answer: SAP/HANA experts say, ADBC should be the choice in this case (even
though EXEC SQL – ENDEXEC would do the same). Not necessarily for any
performance advantage but for the ease of programming, clean OOPs concept,
better error handling and modern method.
3. Can we have secondary Database connection from more than one ABAP
system to single HANA database?
Answer: Yes, we can connect to the same secondary HANA Database system
from more than one ABAP system and use Open SQL to query the data. But if
we need to make sure all the custom tables and extensions to the standard
table is identical in all ABAP system and HANA database (i.e. ABAP-based
system and DDIC information on DB tables is identical).
For example, a custom table YSAPYARD is defined in ABAP system YARD1 with
10 fields and the same table YSAPYARD has two extra fields in ABAP system
YARD2. But the HANA database has been updated with only 10 fields. So, if
someone does SELECT * from system YARD2 (which as 2 extra fields), then
there would be problem as the Database and ABAP system information are not
same.
Answer: No. ADBC is not a HANA specific technology. It is supported for all
ABAP supported database types/operating system combinations. It can be used
for connecting to ORACLE/MSSQL (Microsoft SQL server) etc from ABAP as long
as the ORACLE/MSSQL etc kernel files are loaded into the ABAP system.
Answer: No. The ADBC interface only allows one parameter table, so we cannot
receive more than one table output from one ADBC call. We need to call ADBC
multiple times to return multiple tables.
Like CDS Views, only ABAP transports (ABAP Class/Method) of AMDP needs to
be transported and we need not worry about the corresponding underlying
HANA artifacts. Both CDS and AMDP fall in Top-Down Approach of HANA, which
are recommended by SAP.
We need to be in ABAP system which is on release 7.4 SP05 and higher and
HANA is the primary database. By now you have guessed correctly, AMDP works
only with HANA as the primary database. But AMDP is conceptually designed to
work in any database and any language. This is clear from the way we define
the AMDP Method. We need to let the Method know the database and language.
For HANA, the database is HDB and language is SQLScript.
SAP Document says: Currently, AMDP only supports database procedures from
the SAP HANA database. But in principle, however, AMDP is designed so that
stored procedures from other database systems can also be supported.
AMDP can detect Database independent syntax errors; HANA specific syntax
error and SQL Script errors.
Parameters not passed by value, wrong parameter types etc are database
independent issues. Type mapping checks or wrong default values are HANA
specific errors.
Let us make it more simple. All children who wear the same school uniform
belong to one school. One of those students has a special batch on his/her shirt.
He is identified as the Head Boy/Girl. They have access to all rooms/areas like
any other students and also they have special keys with which they can enter
the areas/rooms which are prohibited for other students.
Let us co-relate the above example with SAP ABAP. All students = CLASS. If a
Class has Marker Interface “IF_AMDP_MARKER_HDB” (student batch) then it is
an AMDP class (head boy/girl). If one or more METHOD of AMDP class has
the keyword “BY DATABASE PROCEDURE” (special key for head
boy/girl), then it is AMDP method.
That’s it. You now know that any class which has a marker interface
“IF_AMDP_MARKER_HDB” and one of its method has the keyword “BY
DATABASE PROCEDURE” is an AMDP class. Period!!
Let us check how an AMDP Class and Method looks in the real scenario.
1
2 CLASS zcl_sapyard_po_amdp DEFINITION
3 PUBLIC
4 FINAL
5 CREATE PUBLIC .
6
7 PUBLIC SECTION.
8
9 INTERFACES if_amdp_marker_hdb.
10
11 * TYPEs here
12 TYPES: BEGIN OF lty_po_data,
13 * field1,
14 * field2,
15 END OF lty_po_data.
16
17 * AMDP Method
18 METHODS get_po_data
19 IMPORTING VALUE(ip_client) TYPE mandt
20 VALUE(ip_lifnr) TYPE s_lifnr
21 EXPORTING VALUE(ex_po_data) TYPE lty_po_data.
22
23 * Non AMDP Method
24 METHODS display_po_data
25 IMPORTING ex_po_data TYPE type lty_po_data.
26
27 PROTECTED SECTION.
28
29 PRIVATE SECTION.
30
31 ENDCLASS.
1
2 CLASS zcl_sapyard_po_amdp IMPLEMENTATION.
3
4 * AMDP Method
5 METHOD get_po_data BY DATABASE PROCEDURE
6 FOR HDB
7 LANGUAGE SQLSCRIPT
8 OPTIONS READ-ONLY
9 USING ekko ekpo.
10
11 * Logic to Select/Join/Loop etc to populate ex_po_data
12 * ex_po_data = logic here
13
14 ENDMETHOD.
15
16 * Non-AMDP Method
17 METHOD display_po_data.
18
19 * Logic to display ex_po_data
20 * ALV Call
21
22 ENDMETHOD.
23
24 ENDCLASS.
25
26
Looking at the interface marker tag (last three letters), it makes us believe that
AMDP is not HANA database specific as it has provision to include other
databases. But for now, let us concentrate only for HDB and wait for further
releases and documentations from SAP where they show AMDP for non-HANA.
Why will they do that?
Looking at the Class DEFINITION, we can guess that the method “get_po_data”
can be an AMDP method as it meets the pre-requisite of passing all parameters
by VALUE. But, just by looking the definition, we cannot say for sure if it really
is an AMDP method. However, we can say for sure that the second method
“display_po_data” is NOT an AMDP method as it does not meet the basic
requirement of passing by VALUE.
To confirm, if the method “get_po_data” is really an AMDP method, we need to
look at the IMPLEMENTATION. In the implementation, if you find the keyword
“BY DATABASE PROCEDURE”, it is AMDP method.
Look the figure below for more clarity on what we spoke above.
Answer: Stored Procedures have been supported by all databases and they can
be called and created using ABAP code. Native SQL was the method to consume
Stored Procedures before ABAP 7.4. Now we can use ADBC as it has better
advantage (OOPs, where-used analysis, exception handling etc) than direct
Native SQL call.
ADBC can be Bottom Up and manage the complete lifecycle of the stored
procedure outside the ABAP stack. We need to make sure, the stored procedure
is deployed in all database systems and we need to take care of different ABAP
database schema names and systems like development box, testing box, quality
box, pre-production and production system.
ADBC can also be Top Down. Surprised!!! Yes, it can follow Top Down
Approach. When we concatenate the native SQL statements in our own program
and call the database and execute those SQL statements, it is Top Down. This
removes the need for handling the database artifacts in each system of the
landscape and all can be handled by the normal transport. But, do you think
creating the complex stored procedure by concatenation strings in ABAP that
easy? You might build native SQL code for simple selects and other normal stuff
and build your program. But complex/actual project requirement is more than
just DEMO program.
And most developer (ABAPers like me) are not familiar with native SQL (and
database language) and ADBC still, lacks native SQL check during compile.
So, the motivation is crystal clear. With ADMP, the creation, modification,
activation and transport are all handled at ABAP layer, i.e. stored
procedure runtime objects on HDB is created and managed by AMDP in ABAP
AS. Also, SQLScript source code is managed at ABAP AS by
AMDP. SQLScript syntax check also happens in HDB (but not in another
database), unlike ADBC.
Answer:
3. Parameters can only be either Table or Scalar. That means, only variables,
structures and simple internal tables can be passed. No deep structures, no
complex tables (tables in a table) i.e. no nested tables.
4. If ABAP Dictionary structures are used for typing, the method cannot be
implemented as an AMDP.
5. Whatever ABAP dictionary tables, views, other procedures etc you want to
use in AMDP Method has to be declared while implementing using keyword
USING (in the above figure, EKKO and EKPO are passed).
Answer: AMDP Method call is not special. They are called like any other normal
class method. But AMDP methods are executed like static methods, even
though they are defined as instance methods.
Answer: When AMDP is executed, the ABAP Kernel calls the database
procedure in the underlying database (SAP HANA).
Before we proceed forward, let us refresh our CDS Concept in SAP HANA.
Answer: From SAP NetWeaver 7.4 SPS 05 i.e. ABAP release 740 Service Pack
Level 05, AMDP can be created in ABAP in Eclipse (Eclipse based environment
i.e. ADT : ABAP Development Tool). We need to be in ABAP Perspective. We
can view the class and methods in SE24 in ABAP workbench (GUI) but
we cannot edit them in GUI. Although AMDPs are created in Eclipse, they are
saved at the ABAP layer. So developers are concerned only with ABAP artifacts.
No need to worry about database artifacts and system handling in different
environments in the same landscape.
AMDPs are defined at ABAP layer but they are dependent on the underlying
database so that they can optimize the database in use at the fullest. As they
are database dependent, the implementation language differs based on the
database. SQLScript is the implementation language for HDB so playing with
AMDP in HDB is same as implementing SQLScript in our ABAP programs. In
another database, the implementing language may not be SQLScript.
Check error message which we get when we try to edit AMDP Class.
Check the Interface tab. You will find “IF_AMDP_MARKER_HDB”. Makes the
class AMDP.
Custom AMDP Class and Method and its usage in custom ABAP program
Provide the package name, Class name you want to create and description.
Provide the Class Definition and Implementation. Do not forget to provide the
Marker interface in the Public section of the Class Definition and the Keywords
in the AMDP Method. The below example shows that both AMDP Method
and non-AMDP Method can co-exist in AMDP Class.
Let us check how we can call the custom AMDP Class in our custom ABAP
Program.
1
2 REPORT zmm_tcode_role_report NO STANDARD PAGE HEADING
3 LINE-COUNT 132.
4
5 *--------------------------------------------------------------------*
6 * DATA DECLARATION
7 *--------------------------------------------------------------------*
8 * Inline data declaration for the AMDP Class Instance
9 DATA(lr_data) = NEW zcl_user_role_amdp( ).
10
11 *--------------------------------------------------------------------*
12 * SELECTION SCREEN
13 *--------------------------------------------------------------------*
14 SELECTION-SCREEN: BEGIN OF BLOCK block1 WITH FRAME TITLE text-t01.
15 PARAMETERS p_tcode TYPE tcode.
16 SELECTION-SCREEN: END OF BLOCK block1.
17
18 *--------------------------------------------------------------------*
19 * INITIALIZATION.
20 *--------------------------------------------------------------------*
21
22 *--------------------------------------------------------------------*
23 * START-OF-SELECTION.
24 *--------------------------------------------------------------------*
25 START-OF-SELECTION.
26
27 * Calling the AMDP method to get the data
28 CALL METHOD lr_data->get_t_code_role_matrix
29 EXPORTING
30 ip_tcode = p_tcode
31 ip_object = 'S_TCODE'
32 ip_langu = sy-langu
33 ip_line = '00000'
34 IMPORTING
35 ex_it_tcode_role = DATA(it_tcode_role).
36
37 *--------------------------------------------------------------------*
38 * If you are in ABAP 740 and SP 5 and above but still not in HANA,
39 * You can connect from Eclipse/HANA Studio and create AMDP but
40 * cannot execute in database layer. You can try below code for
41 * normal Class-Method call.
42 *--------------------------------------------------------------------*
43 ** Normal method call at AS ABAP Layer
44 * CALL METHOD lr_data->get_t_code_role_matrix_nonamdp
45 * EXPORTING
46 * ip_tcode = p_tcode
47 * ip_object = 'S_TCODE'
48 * ip_langu = sy-langu
49 * ip_line = '00000'
50 * IMPORTING
51 * ex_it_tcode_role = DATA(it_tcode_role).
52 *--------------------------------------------------------------------*
53
54 *--------------------------------------------------------------------*
55 * END-OF-SELECTION.
56 *--------------------------------------------------------------------*
57 END-OF-SELECTION.
58
59 * Publishing the data in an output
60 cl_demo_output=>display_data(
61 EXPORTING
62 value = it_tcode_role
63 name = 'AMDP Usage to display the TCode and Role' ).
The output shows two Roles. The program uses AMDP Method.
Find the above Custom Program which consumes the AMDP here.
The above program and AMDP class use one Parameter as an input in the
selection screen. Handling of Parameters are easy. In the next post, we would
show how we can handle the SELECT-OPTIONS in AMDP.
What happens if we change the existing AMDP Method name?
Answer: The method name is automatically updated in the Class which we can
see in the GUI.
Hope this article is clear enough to demonstrate the concept and usage of AMDP
in ABAP Program. In the next articles, we would show more examples of AMDP
programs for different scenarios and also how to Debug them.
If you have not visited the earlier article or if you have not worked in AMDP
earlier, we would sincerely suggest you have a glance of that topic so that you
can understand this and appreciate this article.
In the example demonstrated in the earlier article, all the selection screen
elements were PARAMETERS. Using the PARAMETERS in AMDP Method SELECTs
were straight forward. Today we would show how we can pass SELECT OPTIONs
of the screen to AMDP Methods and use them. Please note, we cannot directly
pass SELECT options as is it to AMDP Methods. This is one limitation of AMDP.
We need to select the data from the database and then APPLY the Filter using
the function APPLY_FILTER.
Let us hit it hard again. AMDP Class-Methods cannot take SELECT
OPTIONS as input. So SELECT OPTIONS need to be converted to FILTER
STRING using some way and then pass the FILTER STRING as
an input PARAMETER of the of the AMDP Method.
The actual syntax to filter the selected data would look like below:
1
2 * Filtration based on Selection screen input
3 ex_it_tcode_role = APPLY_FILTER( :ex_it_tcode_role, :ip_filters );
EX_IT_TCODE_ROLE would have all the data and APPLY_FILTER would keep
the subset using IP_FILTERS value.
1
2 METHODS get_t_code_role_matrix
3 IMPORTING
4 VALUE(ip_object) TYPE agobject
5 VALUE(ip_langu) TYPE menu_spras
6 VALUE(ip_line) TYPE menu_num_5
7 VALUE(ip_filters) TYPE string " PARAMETER for the SELECT OPTION String
8 EXPORTING
9 VALUE(ex_it_tcode_role) TYPE tt_tcode.
Ans: You are the programmer, you find your way to generating the filter.
It should act as the WHERE clause. Or like the FILTER using RANGE table.
1
2 DATA(lv_where) = cl_shdb_seltab=>combine_seltabs(
3 it_named_seltabs = VALUE #(
4 ( name = 'TCODE' dref = REF #( s_tcode[] ) )
5 ( name = 'ROLE' dref = REF #( s_role[] ) )
6 ) ).
If the above syntax is little confusing, then check the alternative for the same
syntax.
1
2 cl_shdb_seltab=>combine_seltabs(
3 EXPORTING
4 it_named_seltabs = VALUE #(
5 ( name = 'TCODE' dref = REF #( s_tcode[] ) )
6 ( name = 'ROLE' dref = REF #( s_role[] ) )
7 )
8 RECEIVING
9 rv_where = DATA(lv_where) ).
I am sure by now you are curious to know how we use it in the Program (after
all you are a programmer by heart).
1
2 *--------------------------------------------------------------------*
3 * Created by: www.sapyard.com
4 * Created on: 29th Nov 2016
5 * Description: This program consumes the AMDP Class/Method and
6 * shows how to send SELECT OPTIONS to AMDP and use
7 * APPLY_FILTER function in AMDP Method.
8 *--------------------------------------------------------------------*
9 REPORT zmm_tcode_role_report NO STANDARD PAGE HEADING
10 LINE-COUNT 132.
11 *--------------------------------------------------------------------*
12 * TABLES
13 *--------------------------------------------------------------------*
14 TABLES: agr_define.
15
16 *--------------------------------------------------------------------*
17 * DATA DECLARATION
18 *--------------------------------------------------------------------*
19 * Inline data declaration for the AMDP Class Instance
20 DATA(lr_data) = NEW zcl_user_role_amdp( ).
21
22 *--------------------------------------------------------------------*
23 * SELECTION SCREEN
24 *--------------------------------------------------------------------*
25 SELECTION-SCREEN: BEGIN OF BLOCK block1 WITH FRAME TITLE text-t01.
26 SELECT-OPTIONS:
27 s_tcode FOR syst-tcode,
28 s_role FOR agr_define-agr_name.
29 SELECTION-SCREEN: END OF BLOCK block1.
30
31 *--------------------------------------------------------------------*
32 * INITIALIZATION.
33 *--------------------------------------------------------------------*
34
35 *--------------------------------------------------------------------*
36 * START-OF-SELECTION.
37 *--------------------------------------------------------------------*
38 START-OF-SELECTION.
39
40 * Build where clause for data fetching
41 * Class-Method to convert the select options to a dynamic where clause which
42 * will be passed to the AMDP for data filteration after data selection
43 DATA(lv_where) = cl_shdb_seltab=>combine_seltabs(
44 it_named_seltabs = VALUE #(
45 ( name = 'TCODE' dref = REF #( s_tcode[] ) )
46 ( name = 'ROLE' dref = REF #( s_role[] ) )
47 ) ).
48
49 * Calling the AMDP method to get the data
50 CALL METHOD lr_data->get_t_code_role_matrix
51 EXPORTING
52 ip_object = 'S_TCODE'
53 ip_langu = sy-langu
54 ip_line = '00000'
55 ip_filters = lv_where
56 IMPORTING
57 ex_it_tcode_role = DATA(it_tcode_role).
58
59 *--------------------------------------------------------------------*
60 * END-OF-SELECTION.
61 *--------------------------------------------------------------------*
62 END-OF-SELECTION.
63
64 * Publishing the data in an output
65 cl_demo_output=>display_data(
66 EXPORTING
67 value = it_tcode_role
68 name = 'AMDP to show APPLY_FILTER function' ).
69 *--------------------------------------------------------------------*
1
2 CLASS zcl_user_role_amdp DEFINITION
3 PUBLIC
4 FINAL
5 CREATE PUBLIC .
6
7 PUBLIC SECTION.
8
9 INTERFACES if_amdp_marker_hdb.
10
11 TYPES:
12 BEGIN OF ty_tcode,
13 tcode TYPE agval,
14 ttext TYPE ttext_stct,
15 role TYPE agr_name,
16 rtext TYPE agr_title,
17 END OF ty_tcode .
18
19 TYPES:
20 tt_tcode TYPE STANDARD TABLE OF ty_tcode .
21
22 METHODS get_t_code_role_matrix
23 IMPORTING
24 VALUE(ip_object) TYPE agobject
25 VALUE(ip_langu) TYPE menu_spras
26 VALUE(ip_line) TYPE menu_num_5
27 VALUE(ip_filters) TYPE string
28 EXPORTING
29 VALUE(ex_it_tcode_role) TYPE tt_tcode.
30
31 PROTECTED SECTION.
32 PRIVATE SECTION.
33
34 ENDCLASS.
35
36 CLASS zcl_user_role_amdp IMPLEMENTATION.
37
38 METHOD get_t_code_role_matrix
39 BY DATABASE PROCEDURE
40 FOR HDB
41 LANGUAGE SQLSCRIPT
42 OPTIONS READ-ONLY
43 USING agr_1251 tstct agr_texts.
44
45 ex_it_tcode_role = select a.low,
46 b.ttext,
47 a.agr_name,
48 c.text
49 from agr_1251 as a
50 inner join tstct as b on a.low = b.tcode
51 inner join agr_texts as c on a.agr_name = c.agr_name
52 where
53 a.mandt = :ip_client
54 AND a.object = :ip_object
55 AND b.sprsl = :ip_langu
56 AND c.spras = :ip_langu
57 AND C.LINE = :ip_line
58 ORDER BY a.low, a.agr_name;
59
60 * Filtration based on Selection screen input
61 ex_it_tcode_role = APPLY_FILTER( :ex_it_tcode_role, :ip_filters );
62
63 ENDMETHOD.
64
65 ENDCLASS.
1
2 CONSTANTS: lc_augdt TYPE augdt VALUE '00000000'. " Clearing Date
3
4 READ TABLE s_budat INTO lst_budat INDEX 1.
5 IF SY-SUBRC = 0.
6 lv_where_augdt = |AUGDT = '| && |{ lc_augdt }| &&
7 |' OR AUGDT > '| && |{ lst_budat-high }'|.
8 ENDIF.
1
2 DATA(lv_where) = cl_shdb_seltab=>combine_seltabs(
3 it_named_seltabs = VALUE #(
4 ( name = 'TCODE' dref = REF #( s_tcode[] ) )
5 ( name = 'ROLE' dref = REF #( s_role[] ) )
6 ) ).
This alternative shown below is a lengthy approach but might be simple and
easy to understand for some of us. After all, everyone has the right to be
different.
1
2 TRY.
3
4 ** Type declaration for getting the Method's input table type compactibility
5 TYPES:
6 BEGIN OF ty_named_dref,
7 name TYPE string,
8 dref TYPE REF TO data,
9 END OF ty_named_dref,
10
11 lt_named_dref TYPE STANDARD TABLE OF ty_named_dref WITH DEFAULT
12 KEY.
13
14 ** Range Table for Select options
15 TYPES:
16 lt_tcode_range_tab TYPE RANGE OF syst_tcode,
17 lt_role_range_tab TYPE RANGE OF agr_name.
18
19 DATA:
20 ls_named_dref TYPE ty_named_dref,
21 lty_named_dref TYPE lt_named_dref,
22 lv_dref TYPE REF TO data.
23
24 FIELD-SYMBOLS: <fs_range_tab_for_sel_option> TYPE ANY TABLE.
25
26 ls_named_dref-name = 'TCODE'.
27
28 CREATE DATA lv_dref TYPE lt_tcode_range_tab.
29
30 ASSIGN lv_dref->* TO <fs_range_tab_for_sel_option>.
31
32 IF <fs_range_tab_for_sel_option> IS ASSIGNED.
33
34 <fs_range_tab_for_sel_option> = s_tcode[].
35 ls_named_dref-dref = lv_dref.
36 APPEND ls_named_dref TO lty_named_dref.
37
38 ENDIF.
39
40 CLEAR: lv_dref, ls_named_dref.
41 UNASSIGN <fs_range_tab_for_sel_option>.
42
43 ls_named_dref-name = 'ROLE'.
44
45 CREATE DATA lv_dref TYPE lt_role_range_tab.
46
47 ASSIGN lv_dref->* TO <fs_range_tab_for_sel_option>.
48
49 IF <fs_range_tab_for_sel_option> IS ASSIGNED.
50
51 <fs_range_tab_for_sel_option> = s_role[].
52 ls_named_dref-dref = lv_dref.
53 APPEND ls_named_dref TO lty_named_dref.
54 CLEAR ls_named_dref.
55
56 ENDIF.
57
58 * Create the WHERE Clause
59 cl_shdb_seltab=>combine_seltabs(
60 EXPORTING
61 it_named_seltabs = lty_named_dref
62 RECEIVING
63 rv_where = DATA(lv_where) ).
64
65 CATCH cx_shdb_exception. "
66
ENDTRY.
Huh!! I am sure by now you are convinced that you would rather spend some
time understanding new syntax at the top of this article than writing this bunch
of redundant codes shown above.
. Our job was to place all the MENU, it is up to you to decide which one you
like.
1
2 * Populating intermediate internal table
3 ex_it_tcode_role = select a.low,
4 b.ttext,
5 a.agr_name,
6 c.text
7 from agr_1251 as a
8 inner join tstct as b on a.low = b.tcode
9 inner join agr_texts as c on a.agr_name = c.agr_name
10 where
11 a.mandt = :ip_client
12 AND a.object = :ip_object
13 AND b.sprsl = :ip_langu
14 AND c.spras = :ip_langu
15 AND C.LINE = :ip_line
16 ORDER BY a.low, a.agr_name;
1
2 * Filtration based on Selection screen input
3 ex_it_tcode_role = APPLY_FILTER( :ex_it_tcode_role, :ip_filters );
Experts suggest wherever possible, we should apply the filter to the DB table
directly and then play around with the resultant data set.
1
2 it_codes = APPLY_FILTER( agr_1251, :ip_code_where_clause);
After the epic is over, let us introduce the main character of our today’s story,
i.e. APPLY_FILTER. The function APPLY_FILTER expect two PARAMETERS.
i – Dataset (example AGR_1251 (DB table, CDS View); :ex_it_tcode_role
(Internal table)) which needs to be filtered.
4. After going through the above information one would have a doubt. Why did
SAP not allow SELECT OPTIONS to be directly used in AMDP as in
normal ABAP?
We feel SAP deliberately chose this path to push down the select option to
database level in accordance with its code to data paradigm shift strategy.
AMDPs are executed directly on the database, hence the select options in the
form of filter string would be executed on the database. On the other hand
SELECT OPTION is just an ABAP language construct which cannot be directly
executed on database level
Are Native and Open SQL competitors? The answer is simple. No. They
have their own identity and usage.
ABAPers would not like if someone tells them that they are not the real SQL
developer.
After all, ABAPer rarely deal with Native SQL. Native SQL is considered
the real SQL for the database in use.
If you see any code between EXEC SQL — ENDEXEC. It is Native SQL syntax.
What are the possible reasons for adopting Native SQL Approach?
Answer:
i) Access tables that are not available on DDIC layer. So, we have not choice
but to use Native SQL.
ii) To use some of the special features supported by DB-Specific SQL, like
passing hints to Oracle Optimizer (for the index which boosts performance) etc.
Answer:
i) One of the not so good properties of Native SQL is that they are loosely
integrated into ABAP.
ii) No syntax check at compile time for Native SQL. Statements are directly sent
to the database system. Handle exception CX_SQL_EXCEPTION
The above drawbacks mean, Developers are responsible for client handling
and accessing correct schema. Developers need to take care of releasing DB
resources, proper locking and handle the COMMIT efficiently.
SAP says:
Open SQL is the only DB abstraction layer with an SQL-like syntax that defines
a common semantic for all SAP-supported databases. Behind the scene, the
Kernel programs are busy converting the Open SQL statement to Native
SQL statements for the database in use.
Open SQL can only work with database tables that have been created in the
ABAP Dictionary.
i) Some limitations of Open SQL removed starting with ABAP 7.4 SP05.
i) Push down data intense computations and calculations to the HANA DB layer
ii) Use arithmetic and string expressions within Open SQL statements
iii) Use computed columns in order to push down computations that would
otherwise be done in long loops.
iv) Use CASE and/or IF..ELSE expressions within the Open SQL.
If you have already read the above points somewhere else, then please ignore
it. Check the below tables for a quick comparison of Native and Open SQL. I am
sure, you have not seen such handy tables elsewhere.
Difference between Native SQL and Open SQL
Search:
Seq Parameters Native Open
No SQL SQL
1 Compilation at ABAP layer No Yes
2 Database dependency Yes No
3 Table buffering possible No Yes
4 All Schema Access Yes No
5 Access ABAP Dictionary No Yes
6 Access to ABAP Core Data Services views No Yes
7 Conversion of SQL staments to new syntax No Yes
without any side effect
8 Possibility of limiting the result set using 'UP No Yes
TO' statement
9 "Keep unnecessary load away from DB No Yes
10 Possibility of Secondary Index No Yes
11 Comparitively faster Aggregation and Yes No
Calculation
12 Strict Syntax check No Yes
13 Consumption of parameterized CDS views No Yes
14 Mandatory use of EXEC SQL statement Yes No
If you have never written a Native SQL code before, please refer to the Native
SQL Example Code Snippet below.
. Please do not ask, why did we not use Open SQL. This is just an example, my
friend. Ideally, we should not be writing Native SQL for EKPO tablewhich is
available in DDIC layer.
Till I get a real database table example, be happy with this EXEC SQL —
ENDEXEC statement.
1
2 TYPES: BEGIN OF ty_ekpo,
3 ebeln TYPE ebeln,
4 ebelp TYPE ebelp,
5 werks TYPE werks_d,
6 END OF ty_ekpo.
7
8 DATA: wa_ekpo TYPE ty_ekpo,
9 it_ekpo TYPE STANDARD TABLE OF ekpo.
10 PARAMETERS p_werks TYPE werks_d.
11
12 *--------------------------------------------------------------------*
13 * Native SQL Begin
14 *--------------------------------------------------------------------*
15 EXEC SQL PERFORMING loop_and_write_output.
16 SELECT EBELN, EBELP, WERKS
17 INTO :wa_ekpo
18 FROM ekpo
19 WHERE werks = :p_werks
20
21 ENDEXEC.
22 *--------------------------------------------------------------------*
23 * Native SQL End
24 *--------------------------------------------------------------------*
25
26 * Subroutine from Native SQL
27 FORM loop_and_write_output.
28 WRITE: / wa_ekpo-ebeln, wa_ekpo-ebelp, wa_ekpo-werks.
29 ENDFORM.
Try to put some wrong syntax between EXEC SQL and ENDEXEC. Syntax
checker would not catch it and your program would activate successfully, but
your program might dump. Do it yourself and have fun.
ABAP on SAP HANA. Part XII. Open
SQL, CDS or AMDP, which Code to
Data Technique to use?
By now, we all have pretty good clarity that CDS Views, AMDP and Open
SQL are not competitors to each other. They all help us to achieve the ‘Code to
Data’ Paradigm shift. They are different tools for the same team and they all
can co-exist.
Yes, all these are used for fetching data from Database. But we have to use the
appropriate tool based on the requirements. Remember, if a needle (read SQL)
can do your job then why worry about a sword (read CDS / AMDP). Similarly, if
the job can be done ONLY by the needle then you cannot achieve the same
result using the sword. After all, “Discretion is the better part of valor“.
ii) CDS views amount to least amount of coding with the ability to be reused in
multiple objects across developments. In another word, it’s a database artifact
that can be consumed across objects/applications
iii) It uses IDA class of SAP GUI hence much faster (kind of paging technique )
AMDP
i) Independent SQL Statement those are not often used in other objects
Open SQL
i) If the SQL queries are for the specific object and won’t be needed elsewhere
(not reusable)
What about the order of preference between Open SQL Vs. CDS?
If a CDS does not exist and you need this SQL only in one program, do not take
the hassle of creating a CDS which would never be used again in another
application. Just go ahead and write your Open SQL.
Please note: Both Open SQL and CDS are OPEN to any underlying database
i.e. they are Platform Independent. And therefore they are the first choice.
If you still doubt our above justification and explanation, then the below Flow
Chart from SAP would help you make the better judgment with confidence.
Before we close, as mentioned in our earlier article New Age Open SQL ABAP
740, at the end of the day, whichever one works best for your project, team
and application, use it. The end user would not see any difference in usability
and result. It is all about maintenance and knowledge of your technical team
members.
HANA has been the buzz word for quite some time and clients, big and small
would eventually move to HANA, tomorrow if not today. So being an ABAPer,
we need to be ready to accept the change and the challenges it would
bring. With in-memory computing, the traditional do and not to do checklist
would become redundant. We need to abreast ourselves with the new
checklist. What was not advised in the pre-HANA era, might be the norm
now. Technically there is not much change, but still, ABAPers need to make a
conscious effort not to program in the traditional mindset. If we are not careful,
we might not be able to harness the full power of the speed beast called HANA.
Worse, we might even witness the negative speed impact because of the wrong
implementation of custom codes in HANA.
Why SAP HANA? What ABAP developers need to understand and learn?
Gone are the days when an ABAP query would take a long time to execute in
SAP due to a great volume of data and ABAP developers would require to
extract these huge volumes of data from the database into the application layer
and the then process this data and do data manipulation through
coding. Developers were given instructions to avoid multiple tables
joins from the database, concentrate on Key fields while data selection
and avoid data calculations especially during select. All data calculations
would be done at the application level in the program after data selection.
Sometimes all data could not be selected due to limit on the volume of data
during select and developer would requirecursor statement to break the
data volume into different data packages, update the internal table for
output display and then select and process the next volume/package. Also,
performance tuning of the data was a major activity required to minimize the
execution time where large data volume of data was involved.
Now with the change of Traditional SAP Database to SAP HANA, one needs to
understand how the previous ABAP development standards would take a U-turn
and many checks followed previously would be irrelevant now. For this, one
needs to understand the basic SAP HANA architecture for better coding
practices.
It’s the columnar database structure and in-memory processing that have
changed the mindset of the basic ABAP coding concept. So now some of the
earlier used data selection standards get changed and some existing becomes
more pronounced.
SELECT * should be replaced with select with specific field names ->this
was however applicable earlier for performance tuning, but now with
the column based structure, this becomes more apparent.
The SELECT statement with ‘CHECK’ should be avoided -> this was,
however, applicable earlier, but now more apparent.
While selecting data, maximum filtering of data should be done in the
where clause. Earlier NE (inequality) was avoided, but now NE filtering is
also advised. With the columnar database, all the columns act as an
index, hence no secondary index creation is required to minimize
execution time. Cursor statement is also not required.Delete after select
also becomes redundant since almost all types of filtering can be done at
one go.
Apply all functions like sum, count, average etc in the SELECT itself
and group themusing ‘group by’.
Instead of sorting after data selection like earlier, use ‘order by’ the fields
required for sorting.
Condition statements like ‘If’, ‘While’, Case’ etc can be applied directly
during SELECT.
Proper joining between tables are required to avoid unnecessary SELECTs
and then ‘Loop’ and ‘Read table’ statements.
So basically what the above points imply that maximum selection and
calculations can be done in one go during single SELECT itself instead of
‘SELECT’, ‘SELECT *** for all entries’, ‘Loop’, calculations like summation,
condition like ‘If’ or ‘Case’ and ‘Append’ to internal table for final display. So
now the lines of coding get reduced, but ABAP developers need to be more
vigilant since more ABAP commands are being clubbed into one SELECT.
Earlier each ABAP statement could be debugged to understand the issues or
solve the defects. But now one needs to be more conscious of the
commands being used and understand their implication.
Some more points which are also applicable, maybe to some specific
requirement are as below.
Basically, if the above points are followed and statements changed accordingly,
the previous ABAP coding can be converted to a HANA one.
Before:
After:
ii. SORT:
Before:
After:
iii. DELETE:
Before:
After:
iv. JOIN:
Before:
After:
On you mark …
1. Definition
The ABAP Test Cockpit (ATC) is a new ABAP check toolset which allows you
to run static checks and unit tests for your ABAP programs.
2. System Availability
The ATC is already available with EhP2 for SAP NetWeaver 7.0 support package
stack 12 (SAP Basis 7.02, SAP Kernel 7.20) and EhP3 for SAP NetWeaver 7.0
support package stack 5 (SAP Basis 7.31, SAP Kernel 7.20).
3. Advantages
The ABAP Test Cockpit is fully integrated with the ABAP development
workbench with high usability for developers and quality experts.
It offers superior and easy to use built-in reporting capabilities with filters
and aggregated levels.
The ABAP Test Cockpit is not only a new check tool but supports essential
quality assurance techniques like quality gates or regression testing in a
consolidation system.
The ABAP Test Cockpit offers a robust process for managing exemptions
(false/positive findings) based on the four-eyes principle.
4. ATC Process
5. ATC Configuration & Management
SAP provides a seamless integration of the ATC framework with the transport
management framework. Upon global activation of ATC at the system level, we
achieve:
Results should be enabled for option “For Any Results”. With this, we are
basically telling the system that ATC checks can be locally run for each object
separately.
ATC Behavior – Enable to block the TR release on priority 1 and priority 2
issues.
Transaction ATC -> ATC Administration -> Exemptions -> Maintain Approvers -
> Double Click
Transaction ATC -> ATC Administration -> Quality Governance -> Subscribe for
Approver Notification -> Double Click
On double click, a pop up would come where you can maintain the delegated
user. The user has to be maintained as “approver” already. You can also restrict
the delegation window with “Start Date” and “End Date”.
5.4 Email Batch Job Scheduling
With exemptions being raised, we would certainly need a mechanism to
intimate the user/approver about the work items that they get. For this, we
have to activate an SAP standard batch job. The activation can be done via
Transaction ATC -> ATC Administration -> Setup -> Schedule Email Jobs ->
Double Click. The batch job can be scheduled as “Weekly” OR “Daily”. If there is
a custom requirement to have scheduling at a higher frequency, then it needs
to done by customer manually.
But, there is a catch – This integration will work only on main TR release level
and NOT during task release.
6. Exemption Process
On running ATC for a single object, the developer has to raise the exemption for
an individual message. “Apply for an exemption” is the link to launch the
exemption workflow.
Object Restriction
This Sub-object – Applicable to the technical object where the code is. An
example of sub-object: Include program.
This Object – Applicable to the global scope of the program. That is the main
program and hence all the ATC issues within that object (including all sub-
objects) are considered.
This Package – The whole package with its objects are considered. The
exemption gets applied to all of them.
Check Restriction
This Check – Applicable to all the “CHECK messages” inside that CHECK. This is
irrespective of the current CHECK MESSAGE since in the screen.
This Check Message – Applicable to ONLY the check message auto populated in
the above screen.
6.2.2 Auto Approver Determination
On clicking on “Continue” button on the ‘Granularity & Scope’ screen, we land
on the “approver selection’ screen as shown below.
In the above screen, the APPROVER field is grayed out and auto-populated. This
is NOT a standard functionality. We need custom enhancement which can do on
the below:
This can be done by maintaining the TMG for the table SATC_CI_REASONS.
The approver can view his inbox via exemption browser. The same can be
reached via
Transaction ATC -> ATC Administration -> Quality Governance -> Exemption
Browser -> Double Click
Implementing the above BADI with some custom code to explicitly call the ATC
framework will help us achieve our target.
The existing ATC issues are as follows. It is visible that 3 of the records are
already approved by the QA lead. But still, we have priority 2 issues.
Error – Priority 1
Warning – Priority 2
Information – Priority 3
Choose the message which you want to change from the below screen. Click on
the ICON and enter a NEW priority the pop-up screen. Click on green ok button.
9. Overall Reporting
Overall reporting can be done via the same transaction.
You could choose from the selection screen as per the requirement and just
choose the required list of the ATC exemption statuses and press F8.
You will see the below screen. With appropriate fields chosen from the layout,
you can build the exemption analysis as desired.
In the below screenshot, you can see that we have important fields like:
Present status
Requestor
Approver
Approval / Rejection Notes
Check / Check message category, etc
Hope this detailed artile would guide you through your first ATC Set up. In case
of any queries, please feel free to contact us.
SAP ABAP on HANA: Part XVIII. SALV
IDA (Integrated Data Access)
Program Construct
Implement “get_requested_fields”
Implement “calculated_line”
Output.
Introduction
Handling huge amount of data of a table often leads to the performance
bottleneck. SAP offers a new version of ALV to deal with the large quantity of
data to be displayed on UI resulting improved response for operations like
sorting, aggregation or filtering etc. The table below shows the advantages of
SALV IDA over traditional SALV.
Program Construct
Step – I: Design Selection Screen
We are going to use T100 table for this SALV IDA. Our selection screen should
look like this –
NOTE: You can also add hard conditions just by creating a reference
otocondition factory.
1
2 * Create Reference for Condition Factory
3 DATA(lo_cond_factory) = lo_salv_ida->condition_factory( ).
4
5 * Set Select Options
6 lo_salv_ida->set_select_options(
7 EXPORTING
8 it_ranges = li_range_pair
9 io_condition = lo_cond_factory->equals(
10 EXPORTING
11 name = 'SPRSL'
12 value = 'E'
13 )
14 ).
Implement “get_requested_fields”
Implement “calculated_line”
1
2 * Create SALV factory
3 cl_salv_gui_table_ida=>create(
4 EXPORTING
5 iv_table_name = 'T100'
6 io_calc_field_handler = NEW lcl_calc_field_handler( ) "Calculated Field Handler
7 RECEIVING
8 ro_alv_gui_table_ida = lo_salv_ida
9 ).
Upon clicking on the hotspot, the row details will be shown. To achieve this
functionality we need to introduce the if_salv_gui_selection_ida interface to
fetch all field information. To display all fields we can make use of the
cl_salv_ida_show_data_row=>display class and method.
Step VII – Handle Toolbar Button (Button Function)
Like any other SALV, it is absolutely possible to add buttons to the application
toolbar and plug in custom functionality upon clicking on them.
“EV_FCODE” should hold the button function code. Remember to check whether
any row is selected or not. Without this condition, if the user clicks on the
button without selecting any row subsequent code will be triggered.
Note – ‘GET_SELECTED_ROW’ is for selecting a single row and
‘GET_SELECTED_RANGE’ is for selecting multiple rows.
You can add your functionality depending upon the value you get in
‘LI_NEW_LINE’ or ‘LI_NEW’.
To add the button, we need to use ‘ADD_BUTTON’. For adding separator use
‘ADD_SEPARATOR’. For selection mode of rows use ‘SET_SELECTION_MODE’.
Selection Screen
Text Search
References
Hope this detailed article would guide you through your first SALV IDA
Development. In case of any queries, please feel free to contact us.