difference between tables and data in abap - abap

I have a question about ABAP:
What is the difference between the two statements:
tables mara.
and
data: test type mara.
is it now quite the same?t

tables mara.
declares an internal table with header, structure of line of the internal table is defined as transparent table mara.
it is proposed not to use a internal table with header, because this is confusing.
data: test type mara.
declares an work area with structure defined as transparent table mara, in another words the structure has same field as the table mara.

The tables statement declares a work area for a data dictionary table/structure and is generally used for logical databases. The data statement is used to create a variable of any type DDIC, local or temporary.
So the tables statement doesn't really let you define any variable you would like and generally should only be used for logical databases since like header lines on internal tables it makes your code somewhat obscure (there is a reason header lines and tables statements are no longer supported in OO Abap).

Related

How to join a table within a user defined function whose name is provided as parameter?

Context
I have three tables in my SQL Server database: 1) School, 2) College, 3) University.
Then I have another table: Tags.
Each of the three tables (School, College, University) can have Tags associated with them. For which purpose I have three association tables: SchoolTags, CollegeTags, UniversityTags.
Problem
I am trying to create a user-defined function that will take the name of association table as parameter (i.e. 'SchoolTags') and the Id of the entity (school/college/university) and will return a list of tags associated with that entityId.
The issue I am having is I have got to join Tags with a table whose name will come in as parameter. For that I am creating a dynamic query. And we can not run dynamic queries in SQL Server user-defined functions.
Question
Any idea how can that be acheived?
Note: I want separate association tables as I have created and do not want to convert them into a generic association table and I do not want to add If-Else based on table names in my function so that if a new association table is created, I do not need to update my function.
I am using Microsoft SQL Server.
Whatever language you are using, you would probably use if:
begin
if table = 'school' then
begin
. . .
end;
else if table = 'college' then
. . .
end;
The exact syntax depends on the scripting language for the database you are using.
What you desire is impossible. You cannot pass a table name as a parameter to a UDF and use dynamic sql in the UDF to then create and execute a statement that is specific to the table passed as the argument. You already know that you have no choice but to use if-else statements in your UDF to achieve your goal - it is your pipe-dream of "never having to update (or verify) your code when the schema changes" (yes - I rephrased it to make your issue more obvious) that is a problem.
There are likely to be other ways of implementing some useful functionality - but I suggest that you are thinking too far ahead and trying to implement generic functions without a clear purpose. And that is a very difficult and trouble-prone path that requires sophisticated tsql skills.
And to re-iterate the prior responses, you have a schema problem. You purposely created three different entities - and now you want a common function to use with any of them. So before you spend much time on this particular aspect, you should take some time to think carefully about how you intend to use (i.e., write queries against) these tables. If you find yourself using unions frequently to combine these entities into a common resultset, then you have might have a mismatch between your actual business and your model (schema) of it.
Consider normalizing your database in related, logical groupings for one EducationInstitution table and one JoinEducTags table. Those tables sound like they maintain the same structure but of different typology and hence should be saved in one table with different Type field for School, College, University, etc.
Then, add necessary constraints, primary/foreign keys for the one-to-many relationship between all three sets:
You never want to keep restructuring your schema (i.e., add tables) for each new type. With this approach, your user-defined function would just need to receive value parameters not identifiers like tables to be run in dynamic querying. Finally, this approach scales better with efficient storage. And as you will see normalization saves on complex querying.

What is the difference in Work area, global structure, internal table?

I am new to ABAP if anyone can tell me a website which I can refer to learn ABAP in depth or to understand it better, I have confusions with this global structures, internal tables, and work areas, someone please explain the need of them clearly with difference in each.
thanks in advance.
Internal tables are a bit like lists in other languages, for instance like a List< T > in c#. They exist only in memory and only within the program they were defined in. I never encountered the term "global structure" as such, but structures are pretty much the same as in other languages. In abap they can be used to define the row structure of tables. Translate this to c# and you would end up with a class X with some properties (your row structure) and a List< X >, your internal table.
Work areas are essentially a single row of a defined structure. Work areas are for instance used to hold the contents of a single row when looping over an internal table. For instance:
data:
it_vbak type standard table of vbak,
wa_vbak type vbak.
select * from vbak into corresponding fields of table it_vbak.
loop at it_vbak into wa_vbak.
....
endloop.
this defines both an internal table it_vbak and a work area wa_vbak. Both are defined using the structure of the DDIC table VBAK, that is one of the SAP ERP tables and contains sales order header data. The example selects some data (in this case: all of it, not a good idea) into the internal table and then loops over the entries in the internal table. At the beginning of each loop, the contents of the current row are transferred to the work area. You can for instance manipulate the contents within the loop and then move the modifications back into the table by using the abap command modify:
modify it_vbak from wa_vbak.
You can define structures both within a program (using the TYPES keyword) and in the SAP ERP Data Dictionary (DDIC). The DDIC is globally available to all programs and contains definitions for tables, structures, views, table definitions, data elements and domains (and a bunch of stuff more which isn't too relevant here).
as a general reference for abap have a look at the SAP Help portal

How to code a superclass in sql

Is there to code a superclass in sql oracle or would you code it as a normal class?
this is a part of my er diagram of my super class:
*Sorry, I'm a beginner with sql
There exist several different approaches for this:
store all data in a single table (this table has columns for all parent and child attributes)
use one table per leaf class, store all attributes in this table (no common table)
use one table per class, store only class-specific attributes in this table (use a common table for the base class data, and add FK references to this table in your detail tables)
I'd recommend you grab a copy of Patterns of Enterprise Architecture - it contains exhaustive information on how to handle situations like this.

SQL - Two foreign keys that have a dependency between them

The current structure is as follows:
Table RowType: RowTypeID
Table RowSubType: RowSubTypeID
FK_RowTypeID
Table ColumnDef: FK_RowTypeID
FK_RowSubTypeID (nullable)
In short, I'm mapping column definitions to rows. In some cases, those rows have subtype(s), which will have column definitions specific to them. Alternatively, I could hang those column definitions that are specific to subtypes off their own table, or I could combine the data in RowType and RowSubType into one table and work with a single ID, but I'm not sure either is a better solution (if anything, I'd lean towards the latter, as we mostly end up pulling ColumnDefs for a given RowType/RowSubType).
Is the current design SQL blasphemy?
If I keep the current structure, how do I maintain that if RowSubTypeID is specified in ColumnDef, that it must correspond to the RowType specified by RowTypeID? Should I try to enforce this with a trigger or am I missing a simple redesign that would solve the problem?
What you're having trouble with is Fourth Normal Form.
Here's the solution:
Table RowSubType: RowSubTypeID
FK_RowTypeID
UNIQUE(FK_RowTypeID, RowSubTypeID)
Table ColumnDef: ColumnDefID
FK_RowTypeID
UNIQUE(ColumnDefID, FK_RowTypeID)
Table ColumnDefSubType: FK_ColumnDefID } compound foreign key to ColumnDef
FK_RowTypeID } }
FK_RowSubTypeID } compound foreign key to RowSubType
You only need to create a row in the ColumnDefSubType table for columns that have a row subtype. But all references are constrained so you can't create an anomaly.
But for what it's worth, I agree with #Seth's comment about possible over-engineering. I'm not sure I understand how you're using these column defs and row types, but it smells like the Inner-Platform Effect anti-pattern. In SQL, just use metadata to define metadata. Don't try to use data to create a dynamic schema.
See also this excellent story: Bad CaRMa.
Re your comment: In your case I'd recommend using Class Table Inheritance or Concrete Table Inheritance. This means defining a separate table per subtype. But each column of your original text record would go into the respective column of the subtype table. That way you don't need to have your rowtype or rowsubtype tables, it's implicit by defining tables for each subtype. And you don't need your columndefs table, that's implicit by the columns defined in your tables.
See also my answer to Product table, many kinds of product, each product has many parameters or my presentation slides Practical Object-Oriented Models in SQL.

Storing polymorphic objects in SQL database

[noob warning!] I need to store some data in some tables where it is like the equivalent of an array of pointers to polymorphic objects. E.g. (pseudo C++)
struct MyData { string name; }
struct MyDataA : MyData { int a,b,c; }
struct MyDataB : MyData { string s; }
MyData * data[100];
I don't really know what google search to enter! How would you store info like this in an SQL database?
My random thoughts:
I could have one table with a column that is the struct identifier and then have redundant columns, but this seems wasteful.
I can have one table for each struct type. These would have a foreign key back to the master array table. But, how do I point to the struct tables?
There's really two major ways to solve this:
table-per-type
table-per-hierarchy
Either of them has its pros and cons.
Table-per-type gives you more tables (one per type), which only store the "delta" from the immediate super class. Worst case, you need to join together a number of tables to finally get all the data together for a single instance of a type. Pros: since you only store what's really relevant for that type into a separate table, you can do this like set NOT NULL restrictions etc. on the database table.
Table-per-hierarchy gives you less tables, but each table represents an entire hierarchy, so it will contains potentially lots of columns which aren't filled (in the rows representating base class types). Also, on the extra columns that make up the derived classes, you cannot set things like NOT NULL restrictions - all those extra columns must be nullable, since they really don't exist in the base classes, so you loose some degree of safety here.
See for yourself - there are two really good articles on how to do this (in Entity Framework, but the principles apply to any database and any data mapping technology):
Demystifying The Code: Table Per Type
Demystifying The Code: Table Per Hierarchy
Hope this helps and gives you some inputs!
Marc
I do the "table-per-sublcass" style from the Hibernate docs.
You make a Person table with all the things you know about a person, plus the PersonID. Then you make a Customer table, with only the data that's unique to a Customer (account balance, etc). Put the PersonID in the Customer table. A WebsiteUser might have a CustomerID in it, and so on down the chain.
One-to-one relationships mapping the IS-A inheritance relationships.
One possibility is an XML field to store the data, this allows searching and retrieving whilst also being relatively easy to serialise. (the question says SQL, but doesn't specify a specfic vendor database, so XML may not work for every DB solution.)
Edit : I'm going to caveat this because it's not entirely clear what needs to be stored / retrieved / purpose etc, so XML may be entirely inappropriate - I'm throwing it out there as a thought provoker instead.