You are on page 1of 24

openSAP

Introduction to Software Development on SAP


HANA
WEEK 3, UNIT 1
00:00:13 Welcome to week three of the introduction to Software Development in SAP HANA. This
week we will explore SQLScript. In unit one well do an introduction to SQLScript. Well
explain what SQLScript is and why you need it. And then in subsequent units in this week,
well have lots of exercises where we go into the system and we create various types of
SQLScript procedures.
00:00:39 So lets go into the introduction to SQLScript. First of all, what is SQLScript? Well SQLScript
is SAPs interface for applications to access SAP HANA.
00:00:50 And its really an extension of standard ANSI SQL so we started with basic SQL and all of the
ANSI SQL statements are compatible with and youre able to execute them from within
SQLScript. Well see that in one of our first examples. Well just write some regular SQL
inside of SQLScript. But SQLScript also has additional language features that we wanted
added.
00:01:17 And every database vendor does this, they have their vendor-specific extensions because no
one wants to break compatibility with SQL. We dont directly add or change things to SQL; we
implement them in an additional language like SQLScript and then this becomes the
language for creating stored procedures in a database.
00:01:39 This is no different than what other major database vendors do with their own implementation
of stored procedures. So inside a stored procedure with writing SQLScript, you have the
ability to have any form of declarative logic, which would mean regular SELECT statements,
as well as we can call to all of our built-in calculation engine functions.
00:02:05 Well talk a little bit more about what calculation engine functions are in a moment. You can
also have various forms of orchestration logic, so you can have all your Data Definition
Language, your DDL. So you can create catalog objects. You can have your create tables,
your create schemas, and you can combine those all up together into a stored procedure.
00:02:28 You can do various data manipulation, or DML. You can have data assignments and,
probably most importantly to making SQLScript a full language that you can write business
logic in as well, we can have imperative logic like IFs and CASEs and EXCEPTIONs and so
forth.
00:02:49 So the main goal for SAP in creating SQLScript was really to allow you to execute as much of
the data-intensive logic inside the database as possible without having to go back to the
application server. Theres two ways that SQLScript makes this possible.
This document contains a transcript of an openSAP video lecture. It is provided without
claim of reliability. If in doubt, refer to the original recording on open.sap.com.
Page2 Copyright/Trademark
00:03:10 The first is that it means that you dont have to transfer any data back to the application
server that would be an intermediate result. It allows us to have data flow from one SQL
statement to another. In the traditional world, we would have to bring the result of every SQL
statement back to the application server and even if we just wanted to feed that in to the next
SQL statement or join the results of two SQL statements.
00:03:36 You couldnt do it in the database as a single SQL statement, even a complex SQL statement
with an inner join or subquery. But if you go beyond that, and many application developers
will do that, theyll bring the data back to the application server layer even if they could use
joins or subqueries because those are harder to write and harder to read.
00:03:56 Its easier just to do data floats. The way our minds think but its not efficient for computer
systems. Well, SQLScript gives you the advantage of being able to write the code in a way
that is very familiar to application developers and is very easy for us to think through the
process.
00:04:14 But at the same time we can optimize it behind the scenes for the best execution that a
computer system like SAP HANA would have. The other thing where we get benefit is that all
your queries are optimized and analyzed both for parallel execution and also just for general
optimization.
00:04:39 So you might write the SQL statements as two separate SQL statements and use
intermediate results between those two, a very common way for application programmers to
do this. Were afraid of using joins or its too complicated to use a join or a subquery so wed
write it as two simpler SELECT statements.
00:04:59 Certainly more readable that way, easier to maintain, easier to write in the first place, but then
not as efficient for the database if its got to perform one SQL statement, store some results,
and go back to the database and get a second set of results.
00:05:14 What SQLScript can do is it can analyze those two statements during compilation and say, I
can combine that down and make that a complex inner join or I can make that a SQL
statement with a subquery. It will do that optimization for you so you dont have to write
those more complex statements.
00:05:33 The other thing that it will do is it will analyze all of your statements and it will see which of
them can be performed in parallel. It will automatically add in this parallelization to your logic.
So as an application programmer you dont have to worry about the technical details of how
the parallelization is happening. You dont have to worry about a threading model, or sync
points, or anything like that.
00:05:59 You write your code. Now theres a couple of things that you probably want to keep in mind
because there is certain types of statements and operations that can throw you out of parallel
mode so you want to be aware of how the system optimizes for parallelization, but you dont
have to really directly code, at least technically, for how the parallelization will happen. This is
all done for you by the SQLScript compiler.
00:06:20 This really lets us create applications that fully leverage the power of HANA, like keeping
logic in the database but also by taking advantage of the massively parallel processing
capabilities of SAP HANA. So if we compare this to if you were to just write plain SQL
statements what kind advantage does SQLScript have over that?
Page3 Copyright/Trademark
00:06:45 Well first of all, in a SQL query, you can only have a single result set. With SQLScript we can
have many exporting parameters. So we can have multiple result sets coming back, which
can be very advantageous. We can bundle all of our logic up, perform multiple SQL
statements even if they are used/combined together and return all of the result sets back to
the application server layer.
00:07:15 This also means that we can take our logic and break it down into smaller chunks. So this
modularization is something all programmers know, we do this in all types of programming,
we like to modularize things. It means its easier to understand, it's easier to maintain. And
probably more importantly, its easier to reuse things if we have a set interface for the inputs
and the outputs, we know what that interface is and all the processing than takes place sort
of in that black box inside that interface.
00:07:47 Well thats exactly what we can do with SQLScript. We can have a fixed input set of
parameters and an output set of parameters and really encapsulate the logic that takes place
inside there, as opposed to regular SQL statements where you dont have any method for
reusability.
00:08:07 So SQLScript also supports the definition of local variables, intermediate variables to either
hold single values or hold entire result sets. So in the traditional world where wed have to
bring those back to an application server because SQL has no language, no semantics to be
able to define intermediate variables.
00:08:27 The only thing we can do is write data into temporary tables or other persistent options like a
globally visible view or something like that to store intermediate results. With SQLScript, this
is just like regular programming. We can declare a variable, it will take on its type when we
set values into it from a statement, well see this illustrated quite extensively in our examples.
00:08:56 And this lets us program like were used to instead of having to adapt and as application
developers program quite differently because we're now down at the database. We want
application developers to continue to be able to program as they always have. And then
finally, SQLScript has control logic, conditional logic, and imperative logic that simply isnt
available as part of SQL.
00:09:23 Regular ANSI SQL is what we would call a declarative language. It does block processing,
not single-record processing. SQLScript has the ability to do everything that SQL does but
also switch into imperative logic and single-record processing so we can loop over a result
set and an immediate variable, process one record at a time. We can have IF statements and
CASE statements. But as youll see a little bit later that comes at a price, because as soon as
you do introduce imperative logic you can no longer have parallel processing.
00:09:57 So just looking at where SQLScript fits into the overall architecture of an application, weve
seen this slide a couple times where weve talked about how the presentation logic executes
completely on the client side.
00:10:11 Then we have control flow logic. This is where we have our service enablement as well as
our control flow logic. This would be at an application server layer. We did talk earlier about
how this application server can collapse down into HANA as well, but this diagram is really
generic, meaning that control flow logic is in any application server.
00:10:33 And then finally we have our calculation logic or our data-intensive logic. Weve been talking
all along about how we want to push logic down into the database, about how we want our
Page4 Copyright/Trademark
data-intensive logic to execute in the database. We havent really said how thats done but
the language for doing that is SQLScript.
00:10:50 Now weve finally reached the point where were ready to talk about how we code that data-
intensive logic. And how this compares to the traditional model? In the traditional world what
wed have to do is wed have our business logic, our application logic, our control flow logic,
all at an application server. This is usually a completely separate piece of hardware. It has to
communicate to the database server over the network.
00:11:18 And therefore it would issue SQL statements. So it would issue SQL statement number one,
get a result set back. That result set has to move across the network and then be stored at
the application server layer. And then, we make another statement, get another result set,
then maybe we merge that result set together or we do some filtering, but basically we have a
lot of data going back and forth.
00:11:43 We can still program that way, even with SAP HANA. So you can still have your job
applications, your ABAP applications and they just do SQL statements. HANA is 100% SQL
compatible, ANSI SQL compatible, so its perfectly possible that you can take your existing
applications and do that but youre still going to have a bottleneck there.
00:12:04 If youre moving massive amounts of data across the network back up to your application
server layer, as soon as you move that data out of HANA, you lose all benefits of in-memory
processing, you lose all benefits of the massively parallel processing that HANA is capable
of. So therefore if your company is investing in HANA to get the utmost performance, but you
dont do anything to change the architecture of your application and just port the database
over to HANA, then youre not going to get the full benefits of SAP HANA.
00:12:31 Then the more logic that you do at this application server layer, the less benefit youre going
to get out of HANA. Now, on the other side, when we talk about re-architecting, when we talk
about doing code pushdown, what we mean is using views, and using SQLScript, so that we
dont have this back and forth from one statement to another between the database server
and the application server.
00:12:56 We can do the data flow from one statement to another completely inside of HANA so that
data never has to come back up out of the database. So we only transfer the final record set,
which is already merged, already filtered, already sorted, aggregated, and that really is the
record set were probably going to display to the end user. Thats a very small data set and
only it is finally returned to the application server layer.
00:13:23 Now a little bit more about parallelization, so this is what I was talking about with
parallelization. In this query we have a select from the product table and then we have a
select from the text table and because both those results are reading from two different tables
and are going into two intermediate variables, those can be processed (in this case its doing
an inner join) so this diagram actually shows it being processed as two different queries.
00:13:58 What will probably actually happen behind the scenes is that itll be combined together into
one join condition and what we have listed as query one and query two here on the slide,
literally written as two separate queries in the code, will actually compress down into one
query when it executes in the database.
00:14:17 Next, we have query three and four. Here were doing a select count for product text and
were doing another select count for a different WHERE condition So even though were
Page5 Copyright/Trademark
reading from the same table, theres no dependencies between these. Theres no WHERE
conditions where its using variables that are dependent upon each other. Were not
combining the two results together in any way. Therefore, these two can be processed
completely in parallel.
00:14:45 And you see that shown here in the diagram. Now theres nothing in the coding that we did
here to tell the system to do it in parallel. We didnt have to have a sync point after query four
that says wait for the completion of query 3 in case it takes longer. We dont have to worry
about any of those things, the SQLScript complier, the internal engine inside of SAP HANA
takes care of all those kinds of details for us.
00:15:08 We can simply write the SQL statements in a way that feels comfortable to us and the system
does the optimizations for us. So, some of the rules about parallel processing. The system
will automatically put all SELECT statements in a procedure and execute them parallelly
unless any of the following occur.
00:15:31 So if you use a local scalar parameter or other variables inside that procedure, as soon as
you access those local parameters it kicks us out of parallel mode because we cant be
changing the same variable or parameter potentially at multiple different points. We cant
maintain the order of the operations at that point, we could overwrite the variable or the
parameter with an older value just because one of the parallel queries took longer than one of
the other ones.
00:16:09 If you have any write operation, so if you change your procedure so its a read/write
procedure and inside there you might set read/write procedures because youre doing
creation operations. So DML or DDL, youre creating a table, youre creating a schema or
something like that, or youre doing dynamic SQL.
00:16:30 So either of these cases require you to create a read/write procedure, its a little flag we set
on the creation of the procedure and those can never be executed in parallel because we
couldnt know what side effects might occur by creating things in parallel.
00:16:47 The other thing that will kick us out of parallel mode is imperative logic. As soon as you
introduce some imperative logic, IF statements, CASE statements, or anything like that, we
kick out of parallel mode because such statements are inherently not parallelizable. They
intentionally process one record at a time.
00:17:07 We need the result of one statement to flow into the next so anytime you have imperative
logic youre kicked out of parallel mode. Obviously as youre building your SQLScript
procedure, you want to make sure if you can, to put imperative logic at the end of the
procedure, that youve already done all of your data selections at the beginning so that they
can be parallelized.
00:17:29 With imperative logic it does mean we drop out of parallel mode as soon as we hit the first
imperative logic statement. So you can have imperative logic mixed into a procedure with
other commands and theyll be parallelized. As soon as you hit your first imperative logic
statement then you kick out of parallel mode and you do not kick back into parallel mode,
even if you would have more select statements afterwards that could be parallelized we dont
go back into parallel mode.
00:17:59 If you have that situation, what you want to do is you want to pull that logic out, write it as a
separate procedure and then do an inner call procedure to branch out to a different
Page6 Copyright/Trademark
procedure that will give the system the ability to re-analyze and see if it can go back into
parallel mode at that point.
00:18:17 And then finally, if you have any SQL statements that are not assigned to a variable. So if you
just issue a SQL statement and you don't move it into a variable or parameter, then that will
kick you out of parallel mode as well.
00:18:33 The data types that we have in SQL for the declaration of parameters or intermediate
variables is all based upon the SQL-92 type system. So you dont have to worry about type
conversions as you move data from your SQL statement into your intermediate variables.
Everything uses the pure SQL type system. This does mean that when we create parameters
we need to declare types. We can create table types so that they can either be locally
available, meaning that theyre specific to one particular procedure, or you can declare global
table types that can be shared across multiple procedures.
00:19:24 But all youre really defining is the structure you want to use in those import or export
parameters of your stored procedure. Here you see two examples, theres a slight difference
in the syntax, two variations in the syntax, we can either say CREATE TABLE TYPE or
CREATE TYPE AS TABLE.
00:19:44 Then you just list the columns you want in your table type and their data types according to
the SQL-92 type system. Now in the editor itself, how we can do this. The procedure editor
(which well see in the next unit once we start creating some procedures) it has a SQLScript
tab where you write the source code, but then it has another tab for Local Table Types and
this is where you put in your CREATE TYPE statements and it will generate types.
00:20:19 These will actually show up as objects in the catalog generated from the procedure itself. The
repository object is a procedure and it contains both the script statements and the table type
definitions. Therefore you could have multiple catalog objects created from a single
procedure object in the content repository.
00:20:41 Now the syntax for creating a stored procedure that uses SQLScript is pretty simple. You see
here we say CREATE PROCEDURE. We give the procedure a name, then we list our input
and output parameters or we can have parameters defined as in-out, as they come in we can
make changes to them and then theyll come out as well.
00:21:01 Then you have to specify the language. The default language is SQLScript. There is one
other language that we support for customers to use and that is the R language. R is an open
source language and we have inoperability with this language. You have to install an R
server separately from your HANA server that allows you to write your R code here in a
procedure.
00:21:30 And we will send that code after checking it to the remote server. Its actually executed over
in the remote R server and the result set is returned to HANA. This is really an interface
mechanism to an external system. R is really good for statistical processing and other forms
of high-end mathematical calculations.
00:21:53 So if you had those kinds of needs you might want to look at the R scenario. We wont talk
about that extensively. Its a bit of a specialized kind of use case and is well-documented in
the SAP HANA developers guide if you want to learn more about that.
00:22:07 We will focus on SQLScript based procedures throughout this week. Next you have to specify
Page7 Copyright/Trademark
the SQL security mode. This allows you to specify if you want the procedure to execute as
the person who defined the procedure or the person whos invoking the procedure. Many
times, you want it to be the person whos invoking the procedure. You want all the commands
that are inside the procedure to run as the user whos executing them, thats the normal
mode.
00:22:40 But sometimes you want commands to be executed that you dont want the person executing
the procedure to have the ability to directly do. You dont want user x,y,z to be able to go to a
command prompt and say Delete table, delete records from table But maybe you do, under
certain business conditions that are controlled, want to allow them to call a procedure that
deletes data from the table.
00:23:09 And you want to encapsulate additional different controls around it. Thats fine. So you can
run it as the definer, the user who defined the procedure, so run it as SYS_REPO in most
cases when we create procedures in the content repository. Then SYS_REPO is the only
user that has to have access to actually delete records.
00:23:31 So someone can call the procedure and have records deleted after the proper checks, but
they cant go directly to the SQL Command Console and issue a DELETE statement.
00:23:41 Next we have the READS SQL DATA, and there we specify if this is a read only or read/write
procedure. And then we have the WITH RESULT set. WITH RESULT set means that it will
create a view for the output parameter of the table; therefore, you can issue a SELECT
statement against this procedure. This would cause the SQLScript procedure to act very
similar to a calculation view, which we saw in the previous week.
00:24:20 So we can define parameters, I showed you here on the left side of the screen you see a
screenshot of the new SQLScript procedure. This is a procedure editor that lets you use the
team provider and a file-based approach to editing. This is the new editor and the one we
recommend that you use moving forward.
00:24:45 Inside this editor we have the ability to declare our local table types inside the source code
editor and then wed simply type or parameters inside parentheses inside a CREATE
PROCEDURE statement. There is a legacy editor, and I will show you this in the next unit
when I go into the system and I create a procedure. Ill do it in the new editor but then I will
switch over to the old editor and show you this as well.
00:25:11 The major difference with the old editor is you cant just type the parameters into an editor.
You have to use this form-based tool to say New Parameter and then it will pop up a dialog
where you fill in the fields and their data types.
00:25:29 And then finally, we need to know how to call a SQLScript procedure and its relatively
simple, its the CALL syntax. So CALL is a statement thats part of regular SQL. Its the
syntax that allows us to call a stored procedure regardless of which language its
implemented in. So you see here an example here where were calling, we give the schema
name, and then we give the procedure name, and then in parentheses we pass in any
importing or exporting parameters.
00:26:02 And then it shows you some of the logic executing. We will also do this in the following units
when we create a procedure. Well go to the SQL Console to test it. Well have to write a
CALL PROCEDURE statement in the SQL Console to execute it. But this is also the syntax
that you would use if you were calling this via J DBC or ODBC. Well see a little bit later, even
Page8 Copyright/Trademark
from server-side J avaScript, we use the CALL statement via the SQL interface to execute
SQLScript stored procedures.
00:26:38 So in this unit weve given you your first introduction to what SQLScript is. Weve talked a
little bit about why you would use it and some of the interface parameters and how we create
them. In the subsequent units in this week, we will spend creating various types of SQLScript
procedures, testing them, and even seeing the interactive debugger.
Page9 Copyright/Trademark
WEEK 3, UNIT 2
00:00:13 This is week three, unit two: Create an SQLScript Procedure with SELECT Statement. In this
unit well go into the HANA system and well see what its like to create a simple SQLScript
procedure. Well focus on using only SELECT statements or just plain SQL. In subsequent
units, well see how we can add in both CE functions and imperative logic.
00:00:42 So maybe just a little bit of a refresher on some basic SQL and some comments on the
SELECT statement. I imagine that many of you, as application developers, are probably
already very familiar with using basic SQL, and the SELECT statement is the most common
of all SQL statements. For most people, this will probably be very much a refresher, but it
helps to still go over things just a bit.
00:01:08 So were going to be using SELECT statements, and the SELECT statement is without a
doubt the most important of all SQL commands, the most widely used. Its how we retrieve
data from the database.
00:01:21 And with the statement, you can really create a lot of complex logic. By using the WHERE
conditions, the GROUP BY conditions, HAVING, and ORDER BY. All these optional
conditions allow us to control how much data and what data is returned from the query from
the database.
00:01:42 So the SELECT row should contain the columns that you want returned from the database.
So we can say SELECT column 1, column 2 or you can say SELECT count and then
some condition you want it to count. Usually you do COUNT* and that returns any records
that meet the rest of the criteria in the following condition.
00:02:11 And then of course you need the FROM, telling the system which table or view that you want
to read from. The WHERE condition gives your main filter criteria to narrow down your
selection. GROUP BY would be when you have summation or any other type of aggregation
taking place. You need to tell the system which columns to use grouping in order to perform
that aggregation. The HAVING is your group condition. And then you have the ORDER BY,
which would control the sort order on your data as it's being returned.
00:02:46 Now one particular point is that you should never really use SELECT* or SELECT SINGLE*. I
think this is a good point regardless of which database that you have. Developers have a
tendency to use SELECT* not because they really need every column in the table, but its a
bit of a lazy pattern. Its easy just to type the * rather than really name off the columns that
you use. Some developers will say Well, but it protects you from, maybe in the future, you
need additional columns and then you don't have to change the SELECT statement. But its
very wasteful, and it's particularly wasteful in any columnar-based database like SAP HANA
is. Because when youre performing a SELECT*, even a SELECT SINGLE, it means that
youre having to move all around the data storage, even if its in-memory, to find the various
pieces of that record and reassemble it. So remember, with columnar-based data, we store
everything in a single column together. In HANAs case it would be in-memory.
00:03:52 As far as you see here, we have all of the IDs of whatever this number is, then all of the
countries, then all of the product types, and then all of the values. And even if youre doing a
SELECT*, that means having to read from one array of memory to find the value 457, and
then having to skip over and read a entirely different array of memory to find the country that
corresponds to that same record. And then so forth for the additional columns. So a lot of
overhead to doing a SELECT*, even a SELECT SINGLE*.
Page10 Copyright/Trademark
00:04:28 And you will find that this is probably the number one thing that hurts performance in a
HANA/in-memory columnar-based database. Youre reading a lot of extra data. Its one thing
to return that to SQLScript as were talking about here, because at least the data is staying
inside the database, but its a whole another thing to return that data to the application server.
00:04:55 So for more general information about any of the HANA SQL syntax, we really recommend
that you go to help.SAP.com. There we have a guide that will talk you through and guide you
through additional information on all the Hana basic SQL syntax. Were not going to go
through all the SQL syntax that you could use in this workshop.
00:05:19 Now lets focus in on creating our stored procedure. We already went to the blocks of the
syntax and what each part means in the CREATE procedure in the preceding unit. The key
that were going to want here to create our first procedure is were going to have to create a
table type that has all the columns in it that we want to return from our SELECT statement.
00:05:41 So its got to match our SELECT column list and have all those fields along with their data
type definitions. And then in the CREATE procedure statement in the parentheses that follow
the name of the procedure, we have to list our input and output parameters.
00:05:57 So were going to take an input parameter of PartnerRole, and then were going to use that
partner role to look up all partner records that have that particular role. Then well return a list
of the partner information, along with the partner addresses that match that information in an
output parameter.
00:06:18 Now a little bit on the code that were going to write here. Were going to have a SELECT and
were going to do a J OIN between two tables. Were going to join the businessPartner table
and the addresses table. This is similar to what we did earlier in the attribute view, except
now were coding it in SQL and putting it inside a stored procedure.
00:06:39 And then well have the syntax we use to test the stored procedure. Well use the CALL
syntax from the SQL Console, and that will cause the execution of the stored procedure and
well see the returned result set displayed in a tabular format.
00:06:56 So lets go into the system and have a look here at how we could create this procedure. So I
will go to the Project Explorer and we will use the team provider file-based approach to create
our procedures. I will show you within this unit what the old modeler-based editor looks like.
The two are still supported and the two are both compatible, so we can edit in one editor and
then switch to the other editor and edit there, but we really recommend the usage of the
newer editor, the source code file-based editor that is here in the Project Explorer.
00:07:46 So I will go to my models and get the name of my procedure that I will be creating. So Ill say
New >File and Ill just put in the file name. I like to put the name of the procedure as my
filename and then .procedure.
00:08:16 Pretty straightforward. That brings up the procedure editor. Its already inserted a bit of a
template for us with the CREATE PROCEDURE statement and weve got the name of the
procedure taken from the file name, and it sets certain things by default. It says the language
is SQLScript; thats correct, we want it to be SQLScript. SQL SECURITY is the INVOKER.
That means whoever executes this, all the statements inside here will run with their database
user security. We could change this if we wanted it to be a DEFINER, but we actually want it
to be INVOKER so thats fine. And then we have READS SQL DATA AS, and this is a read-
only procedure so were all good there.
Page11 Copyright/Trademark
00:09:01 So next we need to create a table type that matches our output parameters. So Ill come over
here to the Local Table Types tab and Ill go ahead and just cut and paste in that table type. I
use the statement CREATE TYPE, give it the name of the type AS TABLE. And then I list
each of the columns that Ill be wanting to return from my SELECT statement and their types.
00:09:31 Now Ill go back to the SQLScript editor and lets get the logic for the procedure. So first of all,
I need to insert the parameters so Ill come here to a statement right after we have the name
of the procedure and Ill put in the input parameter. I want an input parameter of partner role
and I can declare its type in line because it's a scalar parameter. If it would be a table input
parameter, then I would have to go to the local table types and then declare another table
type for it. But for scaler parameters, we can just define those in line in the CREATE
PROCEDURE statement.
00:10:14 Then I have my output parameter, thats my bp_addresses, and it uses the type
tt_bp_addresses, so that is the type we just defined right here.
00:10:25 Now we can go where it says to write your procedure logic and lets just put in our SQL
statement. Here we have our SQL statement. Notice that were saying select various fields
from both A and B, A representing an alias for our business partner table so we dont have to
write this whole long string out every time on each of these columns, and B being an alias for
our address table.
00:10:59 Were going to say join the two on the address ID field from both tables. And our WHERE
condition is where a. PartnerRole =and this is our input parameter. We always but a colon
on the front of it to denote that that is an input parameter. And then the SELECT statement is
being sent into the results. The resulting variable is bp_addresses. Were putting it directly
into the output parameter.
00:11:31 A very simple procedure. Lets go ahead and save it. And we will Activate it. Now lets go
over to the HANA Systems view and lets look here in the catalog. And if we look into
SYS_BIC and go under Procedures, well see this procedure has been activated here.
Theres a catalog representation of this procedure, so its right here:
workshop.sessiona00.models/get_bp_addresses_by_role_sql.
00:12:14 And we would also see the table type get generated as well. So here is the table type that
was declared via the local table types. Now its local table types meaning that the lifecycle
management is managed as part of this procedure. If I change the definition here, it
regenerates it. Its actually a global table type from its execution, I mean its here another
procedure could reference it. If it did reference it, it would have to give it the full name
however. When we declare these local table types we really recommend that theyre only
used inside this procedure, the procedure that theyre declared in, otherwise if one procedure
changes it, it might have a downstream effect and break another procedure. We want to be
careful there. You really have reusable types that are going to be shared by multiple table
types and you would create those directly as an HDB structure in the content repository and
let that generate directly.
00:13:22 So were ready. We could now go test our procedure. So let me grab the syntax to be able to
test this. And then we can do our test from the SQL Console. So the SQL Console lets you
execute any SQL statements. It should really only be used for troubleshooting and testing
purposes, though. Ill go here to the SQL Console, which lets me type in any SQL statements
so I dont have to go write another program to be able to test this procedure. I can test it
Page12 Copyright/Trademark
directly here in the SQL Console.
00:13:59 Notice the CALL statement, thats the SQL syntax for executing a stored procedure. Then I
have to give it the catalog location, so the catalog schema SYS_BIC. Everything thats
generated, all procedures that are generated in the repository are all in SYS_BIC. Then I give
it the package path, workshop.sessiona.00, and then I actually put this in .models, and here
is my get_bp_addresses_by_role_sql, the name of my procedure. Ill pass in partnerrole =02
and Ill get back bp_addresses. Notice it just points to question mark. That means that its an
output parameter and well just display it in the SQL Console.
00:14:57 So well go ahead and execute this, and weve got a syntax error, invalid name of function. I
must have mistyped something. Ill just check here real quick. So
workshop.sessiona.00.models. I should have put in .procedure. Doesnt really matter there,
but you see if you do name the procedure wrong what ends up happening. Thats easy
enough to fix. I changed it and lets just re-execute it. Now it executes correctly and you see
that were seeing all the business partners that have a partner role of 02 and the rest of the
data is displayed here.
00:15:43 One last thing that I want to show you while Im in here. I told you that there was an older
editor that was tied to the SAP HANA Systems view, so this is what we would call the
modeler procedure editor.
00:15:58 If I were to go to my workshop, workshop >sessiona >00, and then go to models, I would
see there is my procedure and I can pull it up in this procedure editor. Now the major
difference here is that its not using the team provider, its not checking out to a local file. This
is an online editor. Its locked this object for editing and I can only edit it when Im connected
to the system. The other major difference is that we just see the code block here. So we only
see the part that occurs between the BEGIN and END. Everything else is actually set via
properties, so we would look here at the properties of this procedure, then we would see that
the Schema, the Run With, Invoker's Rights, the Access Mode Read Only, the Language
SQLScript, these are all properties that have to be set via this Properties tab instead of being
written in to the CREATE PROCEDURE header.
00:17:01 The other difference being that the output parameters, instead of defining them in text, we
have this editor here. So I would bring up this form-based editor to be able to maintain this
information. But as I said, the two are compatible. I could edit the procedure over here now
and activate it from this tool. You just want to be careful if you do make a change in the older
editor, and then you go back to this editor, I would come here and add another comment
here.
00:17:53 So Ill go ahead and save this and activate it. Of course, even if I come back here and
immediately try to edit this, it doesnt show that new comment. You do have to, if you make a
changeif anyone makes a change with the older editorthen you would have to come here
and youd have to do a Team >Checkout in order to get that change. And now I have that
comment.
00:18:32 So you do want to be a little bit careful using both the editors in parallel, so I would really
recommend that you would focus on the new editor. Eventually, the old editor will be made
read-only for backward compatibility only and everyone should be using the new editor, but
weve seen a little bit about how the two do coexist currently in HANA 1.0 SP5.
00:18:54 So in this unit weve seen our first introduction to using the SQLScript editor, weve seen how
Page13 Copyright/Trademark
we can use basic SQL statements inside our SQLScript stored procedures, and how to test
our stored procedures.
Page14 Copyright/Trademark
WEEK 3, UNIT 3
00:00:13 This is week 3, unit 3, Create an SQLScript Procedure with Calculation Engine Functions. In
this unit, we're going to compare what we did in the previous unit, which is to create
SQLScript procedures using only SQL statements to leveraging calculation engine functions
instead of SQL statements.
00:00:33 So you might be wondering, what are calculation engine functions? We saw them a little bit
earlier in the previous week when we created calculation views. We're going to visit them
again, but this time we're going to spend a little more time talking about what they are and
why they can be advantageous over using SELECT statements themselves.
00:00:56 Basically, the CE, or the calculation engine, is the main engine that processes all SQLScript
statements. This is the execution engine for either calculation views or SQLScript-based
stored procedures.
00:01:13 SQLScript itself gets parsed and a lot of processing is done to it. I've already spoken about
how the statements that you write are not necessarily the statements that get executed. The
compilation process will break down your statements, combining things together. It will take
simple SQL statements and combine them together into inner joins. It will turn on parallel
processing, and it does all the determination of when things can be parallelized and when
they can't, and it will turn on all the sync points. So there's a lot of work that the compiler is
doing. And this compilation all takes place inside the calculation engine. We build a
calculation model with a data flow graph, and then the optimizer for the execution of that is
in the calculation engine. And the executor for that model takes place inside the calculation
engine itself. The calculation engine can talk to the database optimizer, and can talk to the
script execution runtime as well.
00:02:21 It's important to note what's going on inside of HANA. So often, we just issue a SQL
statement or access a view. We're not really aware of what is going on deeply inside of
HANA. But as it turns out, there are several engines inside of HANA. There's a calculation
engine. That's where calculation views and SQLScript are executed. Then there's an OLAP
engine for analytic processing. That's where analytical views are executed. And then there's
a join engine, and that's where attribute views are processed. And all this is within the
column store. There's actually a separate row store engine as well. When you combine in
row-based tables, that processing has to be done over in the row store engine. In addition to
all these other engines, we have a SQL optimizer. One of the places where you can
potentially run into less-performant operations than what you might expect is when you have
to transfer control and data between multiple engines. In particular, this is what potentially
happens here if you have SQL statements inside SQLScript. They have to be handed off to
the SQL optimizer. But if you can stay inside the calculation engine, then you save that trip
over to the SQL optimizer for it to have to do some work.
00:03:52 What we've done is we've taken common SQL statements and we've implemented them
directly inside the calculation engine so that we don't have to go over to the SQL optimizer.
The calculation engine can perform the query and return the results directly. And that's what
we call CE functions, or CE built-in functions. It's all the same thing. It's all implementations
of standard SQL statements. Not all SQL statements, but many of them that you would
commonly use, but implemented directly in the calculation engine.
00:04:28 Here are some examples. We saw some of the syntax of the usage of CE functions earlier,
when we did calculation views, because we used the CE functions there as well. In this
case, we have a CE function, CE_CALC_VIEW; that allows us to read data from a view.
Page15 Copyright/Trademark
Then we have a CE_COLUMN_TABLE; that allows us to read data from a database table.
So there are different operations depending upon if you're reading from a view as opposed
to a table. In fact, we'll see in a minute there are even different operations depending on if
you're reading from an attribute view or an analytic view. So you have to know a little bit
more about which object type you're trying to read from. Of course, with a SELECT
statement, you would just say SELECT FROM and then specify the object name. You don't
have get that specific.
00:05:20 You see here we have CE_PROJ ECTION. That's where we can supply a WHERE condition
or narrow our field selection. We have the J OIN. This would be similar to writing a J OIN
statement between two tables or a view and a table. Finally, we're able to select the results
from the intermediate variable. The results, literally the intermediate variable named result,
and put that in an output parameter. We also see how queries can take place in parallel,
take advantage of massively parallel processing. But the whole path, the data flow graph, is
all handled by the SQLScript processor. But in this case, as opposed to the SQL statements
that we did in the previous unit, none of the processing has to go over to the SQL optimizer.
00:06:12 Basically, this allows us to, using the CE functions, the CE functions will encapsulate all the
data transformation functionality and keep it inside the calculation engine. You can still use
SQL statements, but because the CE functions are implemented directly in the calculation
engine, you're going to have the potential to see higher performance, better performance
with the calculation engine functions.
00:06:41 I want to go ahead and take this opportunity to point out: You never want to mix CE
functions and regular SQL statements in the same procedure. Having that mixture means
you still have to go back and forth between the engines. In fact, you're going to have to
transfer over to one engine and then come back to the other. This is a surefire way to have
bad performance. Generally, when customers have escalations, have performance
problems in HANA, this is one of the most common things. They've mixed SQL and CE
functions in the same procedure. That's an absolute no-no.
00:07:20 Let's look at some of the common CE functions that you might use, so the equivalents to
doing this in SQL. The CE_COLUMN_TABLE is the same as doing a regular SELECT
statement against a database table. The difference being that the CE function does not have
to invoke the SQL processor.
00:07:41 A CE_J OIN would perform a J OIN operation between two tables, and we see the
equivalents here. The top part of the example is using the CE_J OIN. Actually, we're doing a
CE_J OIN on it_pubs, it_books, and then doing a second one with different criteria. We see
the same thing done via a SELECT statement and a J OIN condition down at the bottom of
the screen.
00:08:12 The same thing with a PROJ ECTION, a projection applying a WHERE condition. This is
semantically the same as a SELECT statement with a WHERE condition in line in the
SELECT statement. So you begin to see a pattern that the syntax isn't all that much
different, but because of the performance benefit, it's worthwhile taking the little extra effort,
even though most people are probably already very familiar with the SELECT, the SQL
statements. It's worth it to take the time to learn the CE equivalents and to do the little extra
coding that it takes to do those because it will keep you in the calculation engine processor.
00:08:55 This table is really just for your reference. I'm not going to sit here and go through every one
of them, but it's a great table to study. It gives you all the most common SQL statements and
Page16 Copyright/Trademark
then their equivalent CE functions. I might point out what I mentioned earlier, that if you're
doing a SELECT on a column table, that's CE_COLUMN_TABLE. If you're doing a select on
an attribute view, that's CE_J OIN_VIEW, and if you're doing a select on an analytic view,
then it would be CE_OLAP_VIEW. You have to direct the calculation engine to which other
engine it needs to interact with, either the join engine, the column engine, or the OLAP
engine. So you have to be very aware of what type of objects that you are reading from and
interacting with with the CE functions. It's a little extra added bit of complexity, but once
again, it's worth it in the potential performance that you could gain by using the calculation
engine functions.
00:09:53 So now let's go into the system and let's create another procedure. This time, we'll create
one that uses calculation engine functions to do the same thing that we did before using
SQL statements. So I'll come here. This time I'll name it get_bp_addresses_by_role_ce.
procedure. I misspelled procedure, so you see the impact of giving a file the wrong file
extension. It didn't open in the correct editor, so right away I knew I had done something
wrong. That's easy enough to correct. This time I'll actually spell procedure right. There we
are. I get the right icon and I get the right editor. So once again, reinforcing the importance
of the file extensions when working with development artifacts in HANA.
00:10:47 So I'll switch over here and I will get my table type. It is the same table type that we used
before, so just switching from SQL statements to CE functions doesn't impact the table type,
nor does it really impact anything in the header of the procedure, so it's the same input-
output parameters, the same additional metadata information that we would put here as far
as LANGUAGE, SQL INVOKER, READS SQL DATA ASall the same.
00:11:22 So let's now go and get the logic, though. It is a little bit more verbose than if I would use the
SQL statements directly, but here we're going to read from a COLUMN_TABLE,
businessPartners, and then we have the PROJ ECTION on that, so that's where we're going
to supply the WHERE condition. So take our input parameter of partnerrole and feed it into
the PROJ ECTION. Remember, this is the equivalent of a WHERE condition. And once
again, it's not as though this is really having to do an operation where it literally reads all the
records and then supplies a filter. What we're really doing here is we're telling the calculation
engine, point to this table in memory and then retrieve the records with this WHERE
condition, with this filter condition, and these columns.
00:12:17 And then we're doing the same thing with the address, CE_COLUMN_TABLE, read the
addresses. And then we're doing a J OIN on these two intermediate variables, the lt_bp_proj
and the lt_address.
00:12:33 So let's go ahead and save this procedure. And I'll activate it. J ust so you can kind of
compare the two, I'll pull them up side by side here in a split screen. You'll notice it is a little
bit more verbose, as I said, but the potential performance benefits should be worth it. Maybe
give it a try, break with what feels comfortable, with what feels familiar, and give the CE
built-in functions a try.
00:13:11 At this point, I can go ahead over to the SAP systems view and I'll open the SQL Console
here. There it is, SQL Console. And let's cut and paste the test call,
workshop.sessona.00.models. Here we're going to call with the same input parameter value,
the partnerrole =02, and then we'll get our BP addresses back. And we see here, data is
returned. And the thing is, even if we were to say run both of these side by side, we have
such a small amount of data I doubt you would really see a large difference in the test. I
mean, I can go ahead and run them both here.
Page17 Copyright/Trademark
00:14:16 Let's just put the other call in here as well, sessiona.00.models. We can run both of these at
once and you notice I get both results back. So you can confirm that they are identical
results. And you do get runtime on both of these, but I have a feeling that we have a small
enough amount of data that it's going to be really hard to compare the runtimes between the
two. This is an exercise that you can perform in your own system if you are curious, if you
have a larger data set and you're trying to maybe squeeze a little more performance out of
something, you could write a procedure both ways and then do as I did here: execute them
both and compare the runtimes.
00:15:10 In this unit, we've had a look at how we can go beyond just using SQL statements in
SQLScripts or procedures, use the calculation engine built-in functions, and hopefully you've
seen some of the potential value in using the CE functions.
Page18 Copyright/Trademark
WEEK 3, UNIT 4
00:00:13 This is week three, unit four, Creating an SQLScript Procedure with Imperative Logic. In the
previous two units, we've seen two different ways to create SQLScript procedures, either
using SQL statements or using CE functions. In this unit, we want to expand the scope of
what we can use to code SQLScript procedures with, and we'll include imperative logic.
00:00:39 Imperative logic, in general, means that we are processing one record at a time. Unlike
SQL or CE functions that perform bulk operations on an entire record set, this is one
variable or one record at a time. This is probably the kind of syntax that most application
developers are already extremely familiar with. J ust some simple examples before we go
into the system and try this out. In SQLScript, we have IF, ELSE, ENDIF logic. It's very
straightforward. IF, and then you have your Boolean condition, then what lines of operation
you want to take place. ELSEIF, another Boolean expression, and then another THEN, and
then you put multiple lines of execution that you want to take place under that condition.
Similar to IF constructs in other languages, maybe syntactically a little different. You're
used to J ava or J avaScript or ABAP. The syntax is similar. I think it's easy for most any
developer to see it and say, Okay, that's how I do an IF, and adjust their logic accordingly.
00:01:54 We also have WHILE statements, so WHILE, and then a Boolean statement, and then a
DO, and then multiple lines of processing, and then your END WHILE. This is one form of
looping construct, and I think most developers are probably familiar with the concept of a
WHILE. Similarly, we have a FOR loop, which will iterate over a range of numeric values
and binds the current value for a variable in ascending order. This is a good way to loop
over a result set, for instance, and process one record at a time. Those of you that are used
to other programming languages, iterate over an array. Or in the ABAP environment, this
would be similar to a LOOP AT internal table kind of processing.
00:02:48 And then we have the CASE statement. Similar to an IF, but it can be a little nicer way to
write an IF statement. So we've shown you a few examples of the different syntax. Let's go
into the system and let's create a SQLScript procedure that has some of this imperative
logic in it.
00:03:12 Once again, I'll come here to the Project Explorer, go back to my project that we've been
working in, and go to the Models folder. I'll just say New >File and I'll give it the name of
my procedure: get_product_sale_price.procedure. That opens the procedure editor. Let's
go ahead and put in our table type. So what we're going to want to dothis is a little
different than our other two exampleswe're going to want to ultimately return some
product informationthe product ID, the product category, the base price, which will come
out of the databaseand then we want to calculate the sales price. Of course, in the SQL
statement, we could do a little bit of math to just calculate a sales price if it was fixed. But
what we want to do is we want a different multiplier value to get the sale price, basically a
different discount percentage, based upon which product category that we're dealing with.
This is a fairly common type of business requirement, to adjust prices or any kind of
numeric value based upon some other criteria. Traditionally, we would have just read all the
data back to the application server and then done this calculation looping over the data at
the application server. But this shows you how even something like this, this is pretty pure
business logic, can be embedded inside the database and execute here rather than at the
application server layer.
00:04:53 Let's go back to our CREATE PROCEDURE statement, and I will... in my input parameters
we want to put in a particular product ID, and then we'll output the product sale price table
for that product ID.
Page19 Copyright/Trademark
00:05:15 Let's get our source code. You'll notice that there's a bit more source code here, but it
provides some interesting learning opportunities. Let's go ahead and put it in here. First of
all, we have the DECLARE statement. This is not something that we've really seen before.
All of our intermediate variables up to this point have been taken from either the result set
of a SELECT statement or the result set of a CE function, so they automatically take on
their data type based upon whatever data is being passed into them. So we didn't need to
do any sort of data declaration or type information about that variable before its use. In this
case, we're going to have some variables, traditional variables, that will be used either as a
scalar value to perform part of this calculation in our imperative logic. Therefore we do have
to declare them, and we have to give them a data type. So we're going to declare this
lv_category. It's going to be a character field, 40 characters long, and we're going to set it
initially to null. Then we're going to declare a discount and it's going to be a decimal 15,
with a scale of 2. We're going to set it initially to zero. We go ahead and we have our
SELECT statement here, where we're going to select the product ID, the category, and the
price for a record from the products table where the product ID is equal to our input
parameter. Likewise, we could have used a CE function at this point. It didn't really matter,
performance-wise, for this particular procedure. We're returning, realistically, one record
because we're passing it a product ID so that's the unique key of the products table, so
returning one record, it's not going to matter much.
00:07:19 Then we're going to select the category into the lv_category from lt_product. This is a little
bit of an interesting concept. In other programming languages, you would probably take this
result setor, in this case, it's flat, it's one record, so it's like a structureand you would
probably try to access a sub-part of that structure. But everything in SQLScript revolves
around SQL syntax, so we can perform a SELECT statement even on another variable.
That's exactly what we're doing here. We're basically telling it okay, lt_products, single
record. Let's get the category field from the lt_product structure and put it into this other
intermediate variable so that we can use it in our imperative logic. That's all that we're
doing here.
00:08:14 Now we have our imperative logic, so simple IF statement, IF lv_category is 'Notebooks',
THEN make the discount 20%. If it's 'Handhelds', then it's 25%, and 'Flat screens' 30%.
Here we have a LIKE statement, so IF lv_category is LIKE 'Printers,' because we've got a
couple different types of printers, so we've wildcarded that value, that comparison, and the
discount is 30%. Any other conditions, so just a simple ELSE statement, then there's no
discount.
00:08:49 Now we can fill the output structure, the product_sale_price. We'll select the ProductID,
the Category, and the Price from lt_product. Once again, we're just taking fields from
that result set, putting it in the output, but then we're also able to calculate the fourth
column, which would be the discount. So we'll take Price, minus, and then we cast the
result of price times our discount, and then we have to say as decimal(15,2) to make sure
that it keeps it as a decimal, the right type and length. And then we say as SalePrice. That
will make sure that it puts it back into the SalePrice column of our output table.
00:09:39 So you've seen some interesting things going on here, both in the form of usage of
imperative logic, but also how we can read parts of the data, read variables, out of result
setsin this case, we have to do that because we can't use the result set directly in our
imperative logic. We have to do the SELECT to put it back into another intermediate result.
00:10:04 Let's go ahead and Save. And then Activate. It's successful. Now we can test. I'll go back to
Page20 Copyright/Trademark
the SQL Console in order to test. Let's get our test procedure, sessiona.00.models, and
we're going to pass in HT-1000, that's a certain product. We'll get the product sale price,
and that will be returned in the SQL Console. And here we see that HT-1000. It's
notebooks. The price is $956, but the sale price is $764. Maybe just to compare this, that's
a notebook, let's run this now with some of the other products that we have in our
database. Let's just run this with HT-1002. So now we see that they happen to both be
notebooks. Let's just check this real quick. Let's get another record so that we can compare
and make sure that our calculation is really working correctly. So let's just browse the
product table. I did the definition...content...there we are. So let's skip ahead. Okay, HT-
1030, that will get us...product category...there we are. So execute both of those
statements once again, and here we see the result of the notebook with its sale price, and
the result of the flat screen with a greater discount amount. You can see how we can test
our SQLScript procedure pretty easily. I hope this has broadened your understanding of
what we can do in SQLScript procedures and how we can really begin to move not just our
data logic, but also begin to take some of our business logic and move it down into the
database as well through the usage of imperative logic inside of SQLScript.
Page21 Copyright/Trademark
WEEK 3, UNIT 5
00:00:13 This is week three, unit five: Using the SQLScript Debugger. So far in this week weve seen
how to build SQLScript procedures. Weve seen various syntax approaches both with SQL
statements, CE functions, and imperative logic.
00:00:31 Of course the more logic that you write down in the database in the form of stored
procedures, the more you need a good tool to be able to debug whats going on. Particularly
as you start writing imperative logic and you have intermediate variables, often in order to
troubleshoot, you need to see what are the values of those intermediate variables at runtime.
00:00:52 Well luckily, as of HANA 1.0 SP5, we have a full interactive debugger and thats what were
going to have a look at in this unit. So because HANA studio is based all on Eclipse, running
inside the Eclipse framework, were able to take the standard Eclipse debugger and use that
for our SQLScript debugger as well.
00:01:16 The standard Eclipse debugger has several parts to it. Up in the top left-hand corner we have
the Debug Session. This shows us which server were connected to and which debug
session were currently in. In the top right-hand corner, we have our Watch area, that would
have a listing of our breakpoints and it would show us all of our variables.
00:01:41 And from there well be able to see values inside those variables as well. And in the bottom,
we have the Code so we can see which line of code were currently debugging. Now there
are a couple of steps that you need to go through in order to have the proper debug
privileges.
00:02:00 So basically your user either needs a role that has these privileges or they have to be
granted directly to you. So youre going to need some access to the SYS_BIC schema so
youre able to access the privileges themselves and execute them. And then youre going to
need the DEBUG (SYS) procedure with EXECUTE privilege.
00:02:21 So let me show you what this looks like. Ill go to my user ID, go to the Security folder, look at
the user ID that Im using for this workshop, and we actually have it in one of the roles. We
dont have anything directly granted to our user ID, well, with the exception of some system
privileges that I added that werent in any role.
00:02:47 But everything else is done via the roles and its actually here in the admin workshop_user
role. This is a role I created for everyone doing the exercises in this workshop, so it has
everything you need in order to do the workshop. Most importantly, we have access to the
SYS_BIC schema and we have the DEBUG (SYS) authorization. You have to have execute
to DEBUG (SYS) procedure. So thats what you would need in order to be able to debug
SQLScript procedures.
00:03:28 Now the debugging process is pretty straightforward. You pull up your procedure in the
procedure editor and you can double-click in the area next to the line numbering, and that will
set a breakpoint. You can also right mouse click and say Set Breakpoint.
00:03:46 Its important to note that this is one of the reasons why you really want to start to use the
new procedure editor, the file-based procedure editor, because you cannot separate points in
the old editor.
00:03:58 So you remember back a few units ago where I showed you that you could create
procedures and edit them in the new source-code-based file editor that sits as part of your
Page22 Copyright/Trademark
project in the team provider. Or you can create them in what we call the navigator editor, the
modeler editor, and thats over in the SAP Systems view.
00:04:19 Well one of the other major differences that I didnt denote earlier because we hadnt talked
about debugging yet is that you can only separate points in the new editor. And then once
you start the debugger, you see...we'll go in the system in a minute and see this, see our
service code down in the bottom left corner and we see the breakpoints.
00:04:42 So you need to create a debug session first so you would choose the little bug icon and then
choose Debug Configurations and create a SQLScript procedure configuration. Right now
you only have to do this once, and theres really no configuration that has to be maintained
for this, so we dont have to maintain ports or anything like that. Its automatically going to
use the SQL connection of the HANA studio. Thats how it connects to the server for
debugging purposes as well. Theres no special debug port or anything like that.
00:05:19 One important point that I should make is that currently, we have a limitation that we cannot
debug procedures that have input parameters. So theres nothing, theres no dialog that will
come up and ask you for the input parameters. Therefore, we often have to write a wrapper
procedure around our existing procedure in order to debug it. Well see this in the exercise.
00:05:48 Now once you start the debugger youll see that the debugger stops on any of your chosen
breakpoints. Another limitation that we currently have is that you cannot single step in the
debugger, you can only jump from one breakpoint to another.
00:06:01 Therefore if you think you might want to see the variables at multiple points in the execution
of your procedure, you should set multiple breakpoints in advance. Once the execution does
stop on a particular breakpoint, youll see all the variable display and youll see the values for
any scaler variables and youll see the number of rows listed for any table variables. You can
then right mouse click on a table variable and it will open an additional screen that will show
you all the record details that are in that variable.
00:06:37 So lets go back to the HANA studio, go to the Project Explorer, and we want to debug one of
our procedures, but first were going to have to create this wrapper procedure.
00:06:50 So lets say debug wrapper, New >File >debug_wrapper.procedure. Well have no input
or output parameters in this procedure, so theres no types that we have to create. We really
only need one line here to call our other procedure, so were going to test our procedure that
has imperative logic in it.
00:07:27 So lets adjust this so it points to our procedure, so sessiona.00.models and were going to
pass in HT-1000. So lets go ahead and save this and I will Activate. Right, so now we can
set a breakpoint here in the wrapper. You always have to set a breakpoint in the wrapper
because thats actually the procedure were going to execute.
00:08:05 Then lets also go into our get_product_sale_price and set one here, and set one here as
well. And like I said, we can also right mouse click and say Toggle Breakpoint, that would set
one as well. So now at this point lets switch to the Debug perspective, if you do not see the
Debug perspective up here in the corner of your screen like it is in mine, you can always say
Open Perspective and choose it from here and that will add it to the window.
00:08:39 So well switch to Debug perspective. We can see our breakpoints set here and we can see
both of our procedures. Now what you want to do is you want to be sure that you have the
Page23 Copyright/Trademark
debug wrapper procedure highlighted. If I have this procedure highlighted, if the focus is on it
and I try to start the debugger, then its going to fail because this one has input parameters.
So it doesnt know which one you want to debug other than which one is the selected tab.
00:09:06 So we will debug with this one. Well come up here to the little bug icon and well say Debug
Configurations, Ive never debugged on this system so the first time I have to create a new
debug configuration so Ill just call this SQLScript. Notice there are no parameters, theres
nothing to fill out here in this diagram. Eventually, there will be debug configuration. In a
future revision, well add the ability to execute procedures that have input parameters and
what youll have to do is have a SQLScript procedure debug configuration. And in this debug
configuration, youll see the input parameters and youll have to fill in a value and save it as
part of the debug configuration. For now Ill just apply this configuration, Ill say Debug, it will
connect, and its running, and we see that weve already stopped here.
00:10:07 Now theres nothing real interesting to see because were just in the initial part here, so well
say Resume. That will go to the next breakpoint and already we can see our category is
null. Our discount is 0. We have one record in our LT_PRODUCT right now, and if you
want to see the details of that one row you would say Open Data Preview. It opens down
here and we can see the current values as well, so we can already see what values were
getting there.
00:10:40 So lets go ahead to the next breakpoint. Now we can see which discount has been
calculated, so already were beginning to be able to have enough information to debug and
maybe we saw, Oh, its notebooks, but we have the wrong discount coded in the program. I
shouldnt have 20, I should have something else.
00:11:01 This is a simple example but hopefully it demonstrates to you how powerful the SQLScript
debugger is, particularly with the ability to look at the data values that are in a table
parameter. And youve seen how you can use this to debug your procedures, which then
supports you being able to write more of your business logic down in the database layer.
2013 SAP AG or an SAP affiliate company. All rights reserved.
No part of this publication may be reproduced or transmitted in any form
or for any purpose without the express permission of SAP AG. The
information contained herein may be changed without prior notice.
Some software products marketed by SAP AG and its distributors
contain proprietary software components of other software vendors.
National product specifications may vary.
These materials are provided by SAP AG and its affiliated companies
("SAP Group") for informational purposes only, without representation or
warranty of any kind, and SAP Group shall not be liable for errors or
omissions with respect to the materials. The only warranties for SAP
Group products and services are those that are set forth in the express
warranty statements accompanying such products and services, if any.
Nothing herein should be construed as constituting an additional
warranty.
SAP and other SAP products and services mentioned herein as well as
their respective logos are trademarks or registered trademarks of SAP
AG in Germany and other countries.
Please see http://www.sap.com/corporate-en/legal/copyright/index.epx
for additional trademark information and notices.
w w w .sap.c om