Unknown token in SQL select where statement - sql

I have three tables:
PRESS Table : ID, NAME
REGIONS Table : ID, NAME
Each "Press" is published in certain areas (Regions), so I created a child table called "PRESSREGIONS" :
PRESSREGIONS : ID, NAME, IDPRESS
When trying to select records from PRESSREGIONS related to the current PRESS, I use:
SELECT * FROM PRESSREGION WHERE PRESSREGION.IDPRESS = PRESS.ID
I have the following error:
ERROR -206 TOKEN UNKNOWN PRESS.ID
I even tried with another table and another field just to try and got the same error. Is there anything wrong with my statement?
Delphi RIO 10.3 - Firedac - Firebird 3.0

You need to JOIN with PRESS.
SELECT
pr.*,
p.*
FROM
PRESSREGION AS pr
INNER JOIN PRESS AS p ON pr.IDPRESS = p.ID

You can not use PRESS.id because you did not declared PRESS as something you are going to use.
"Translating" to Delphi your queries would look like having two files:
Unit A;
inteface
var AAA: integer;
implementation
end.
and then
Program B;
begin
AAA := 10;
end.
Trying to compile the program - you would receive just the same error, variable AAA was not defined, the token AAA is not known to the Delphi compiler when compiling the module B. Until you either explicitly declare B-local variable AAA or explicitly declare your intention to import AAA variable from the unit A of all existing units (Program B; uses A; ...) - the program would not compile.
If the compiler can not know with absolute warranty what you intended to do - it can not do guesswork and write the program for you by somewhat random estimations.
Same with SQL, unless you explicitly declare the table PRESS (maybe with a shortcut/alias) as something you do have intent to use - the query compiler would not know.
Read chapter chapter 6.1.3. The FROM clause from Firebird documentation.
Or Martin Gruber's "Essential SQL".
Or there were good beginners books for Delphi 3 and Delphi 5 in Russian and probably in other languages too. Actually, "vast and generic scope, shallow depth" beginners books about SQL databases might do better service to you as of yet, than very detailed "narrow scope in-depth" kinds of documentation.
On option to explicitly declare that would be, in SQL'89 flavor "implicit join" way
SELECT * FROM PRESSREGIONs, Press WHERE PRESSREGIONs.IDPRESS = PRESS.ID
Another option, quoted above by Dai, using SQL'92 "explicit join" flavor would be
SELECT * FROM PRESSREGIONs JOIN Press ON PRESSREGIONs.IDPRESS = PRESS.ID
See more SQL commands and Firebird's reactions to them at https://dbfiddle.uk/?rdbms=firebird_3.0&fiddle=8f32007629284cf0aa30128d5a7b5e10

Related

OpenSQL uses additives that can only be used with a fixed point arithmetic flag?

I keep having an error message for the selection below. What I have done is creating a global structure, then declaring a structure and a table in the program as TYPE table, as it is seen below:
DATA: gt_add_data_08 TYPE TABLE OF zsd_s_z5_9910_9900_08,
gs_add_data_08 TYPE zsd_s_z5_9910_9900_08.
The selection that I have problem is below:
SELECT gt_add_data_08~bi_desc1,
gt_add_data_08~bi_desc2,
gt_add_data_08~herkl,
gt_add_data_08~herkl_t,
gt_add_data_08~tempb,
gt_add_data_08~tbtxt,
vbdpl~lfimg,
vbdpl~vrkme,
vbdpl-charg
INTO TABLE gs_add_data_08
FROM gt_add_data_08
INNER JOIN vbdpl ON
vbdpl~posnr = gt_add_data_08~posnr,
vbdpl~vbeln = gt_add_data_08~vbeln
WHERE vbdpl~spras = 'EN'.
The selection is supposed to join two tables, thus gt_add_data_08 and vbdpl into gs_add_data_08, with the condition that spras must be in English. The error that is show to me is:
This Open SQL statement uses additives that can only be used with a fixed point arithmetic flag enabled (e.g. CASE Expression, Host variables in expressions, ...)
May anyone know where the problem may be that is showing to me this error?
Thank you all in advance!

Does the less than symbol in SQL serve another purpose other than being a operator?

I had a vendor write a script for us and we are receiving errors pertaining to the line
WHERE 1=1 AND student.calendarID = <selected Calendar>.
I have never seen the syntax "<selected abc>". May someone please explain this to me? Its returning an error for that line as well. I'm using MS SQL Server.
SELECT DISTINCT student.personID
FROM student
join TranscriptCourse tc on tc.personID = student.personID
join TranscriptCourse tc2 on tc2.personID = tc.personID and tc.coursenumber = tc2.coursenumber
WHERE 1=1 AND student.calendarID = <selected Calendar>
AND student.endYear = <selected Year>
AND student.structureID = <selected Schedule>
and tc.gpavalue > 69 and tc2.gpavalue > 69
and tc.transcriptID > tc2.transcriptID
and tc.grade in ('09','10','11','12')
and tc2.grade in ('09','10','11','12')
It looks to me like incorectly used Template Parameters
If used properly in format <parametername, parametertype, defaulvalue> eg <SelectedCalendar, int , 0> you can then use Query > Spefify Values for Template Parameters or Ctrl+Shift+M shortcut and you'll get a window where you can fill values for each template:
Angle brackets are common computer science & software engineering programming language definition meta-characters, aka characters of the notation used to talk about programs, aka a character of a meta-language, aka meta-notation. (Not to be confused with a different meaning for characters treated specially compared to other characters by a system.) In informal communication about programs our metalanguage tends to be natural language plus bits stolen from more formal notations.
Typically <x> means a generic expression of type x that you would replace by program text.
So <selected Schedule> would just mean some language text for a value identifying a a schedule. It's pseudo-code for a parameter.

How to tell if an identifier is being assigned or referenced? (FLEX/BISON)

So, I'm writing a language using flex/bison and I'm having difficulty with implementing identifiers, specifically when it comes to knowing when you're looking at an assignment or a reference,
for example:
1) A = 1+2
2) B + C (where B and C have already been assigned values)
Example one I can work out by returning an ID token from flex to bison, and just following a grammar that recognizes that 1+2 is an integer expression, putting A into the symbol table, and setting its value.
examples two and three are more difficult for me because: after going through my lexer, what's being returned in ex.2 to bison is "ID PLUS ID" -> I have a grammar that recognizes arithmetic expressions for numerical values, like INT PLUS INT (which would produce an INT), or DOUBLE MINUS INT (which would produce a DOUBLE). if I have "ID PLUS ID", how do I know what type the return value is?
Here's the best idea that I've come up with so far: When tokenizing, every time an ID comes up, I search for its value and type in the symbol table and switch out the ID token with its respective information; for example: while tokenizing, I come across B, which has a regex that matches it as being an ID. I look in my symbol table and see that it has a value of 51.2 and is a DOUBLE. So instead of returning ID, with a value of B to bison, I'm returning DOUBLE with a value of 51.2
I have two different solutions that contradict each other. Here's why: if I want to assign a value to an ID, I would say to my compiler A = 5. In this situation, if I'm using my previously described solution, What I'm going to get after everything is tokenized might be, INT ASGN INT, or STRING ASGN INT, etc... So, in this case, I would use the former solution, as opposed to the latter.
My question would be: what kind of logical device do I use to help my compiler know which solution to use?
NOTE: I didn't think it necessary to post source code to describe my conundrum, but I will if anyone could use it effectively as a reference to help me understand their input on this topic.
Thank you.
The usual way is to have a yacc/bison rule like:
expr: ID { $$ = lookupId($1); }
where the the lookupId function looks up a symbol in the symbol table and returns its type and value (or type and storage location if you're writing a compiler rather than a strict interpreter). Then, your other expr rules don't need to care whether their operands come from constants or symbols or other expressions:
expr: expr '+' expr { $$ = DoAddition($1, $3); }
The function DoAddition takes the types and values (or locations) for its two operands and either adds them, producing a result, or produces code to do the addition at run time.
If possible redesign your language so that the situation is unambiguous. This is why even Javascript has var.
Otherwise you're going to need to disambiguate via semantic rules, for example that the first use of an identifier is its declaration. I don't see what the problem is with your case (2): just generate the appropriate code. If B and C haven't been used yet, a value-reading use like this should be illegal, but that involves you in control flow analysis if taken to the Nth degree of accuracy, so you might prefer to assume initial values of zero.
In any case you can see that it's fundamentally a language design problem rather than a coding problem.

Retrieving Object names and Transfer requests for an entire package programmatically

I have two separate system (development and testing) and I need to check that for all my objects (programs and all includes) the version in development matches that in dev. I can do this manually by going to SE80 -> Utilities -> Version Management for each object but for hundreds/thousands of objects this is extremely time consuming.
Is there a way to retrieve the object name and TR programatically so that they could be output to a table or spreadsheet?
EDIT. (Vwgert it seems to me like this works - if it doesn't could you explain a bit more why it won't? Thanks)
So using the following JOIN I believe I am able to retrieve all the objects, types and latest TR in the system.
SELECT a~obj_name b~korrnum c~object b~datum b~zeit
FROM tadir AS a
INNER JOIN vrsd AS b
ON a~obj_name = b~objname
INNER JOIN e071 AS c
ON a~obj_name = c~obj_name
AND a~pgmid = c~pgmid
AND a~object = c~object
INTO TABLE gt_obj_tr
WHERE a~devclass IN s_pkg.
SORT gt_obj_tr BY object ASCENDING obj_name ASCENDING korrnum DESCENDING datum DESCENDING zeit DESCENDING.
DELETE ADJACENT DUPLICATES FROM gt_obj_tr COMPARING object obj_name.
You can find most of the object headers in the table TADIR. The request and task headers are stored in E070, the entries in E071 - just take a look at the contents, it's fairly self-explanatory if you know what a transport looks like. Be aware that some object types can be transported partially (R3TR CLAS is the entire class, LIMU METH is only a single method) - this makes direct joins impossible.
Probably the easiest (although not pretty) is to use table REPOSRC and link that to VSRD. REPOSRC is the table containing all the source code (methods, programs, functions) in the system so you can be sure you don't miss anything. You'll probably do something like (rough pseudo code):
SELECT name FROM reposrc
WHERE name LIKE 'Z%'
OR name LIKE 'SAPLZ%'
OR name LIKE 'SAPMZ%'
SELECT objtype objname FROM vrsd
WHERE objname = reposrc-name
AND objtype IN ('CINC', 'REPS') "Class include & reports
This of course is just source code but it sounds like thats all you need. If you need to get from the report name to the real abap object (method, class, function module) use function module SEO_CLASS_GET_NAME_BY_INCLUDE and for functions look it up on table TFDIR.

How to quote values for LuaSQL?

LuaSQL, which seems to be the canonical library for most SQL database systems in Lua, doesn't seem to have any facilities for quoting/escaping values in queries. I'm writing an application that uses SQLite as a backend, and I'd love to use an interface like the one specified by Python's DB-API:
c.execute('select * from stocks where symbol=?', t)
but I'd even settle for something even dumber, like:
conn:execute("select * from stocks where symbol=" + luasql.sqlite.quote(t))
Are there any other Lua libraries that support quoting for SQLite? (LuaSQLite3 doesn't seem to.) Or am I missing something about LuaSQL? I'm worried about rolling my own solution (with regexes or something) and getting it wrong. Should I just write a wrapper for sqlite3_snprintf?
I haven't looked at LuaSQL in a while but last time I checked it didn't support it. I use Lua-Sqlite3.
require("sqlite3")
db = sqlite3.open_memory()
db:exec[[ CREATE TABLE tbl( first_name TEXT, last_name TEXT ); ]]
stmt = db:prepare[[ INSERT INTO tbl(first_name, last_name) VALUES(:first_name, :last_name) ]]
stmt:bind({first_name="hawkeye", last_name="pierce"}):exec()
stmt:bind({first_name="henry", last_name="blake"}):exec()
for r in db:rows("SELECT * FROM tbl") do
print(r.first_name,r.last_name)
end
LuaSQLite3 as well an any other low level binding to SQLite offers prepared statements with variable parameters; these use methods to bind values to the statement parameters. Since SQLite does not interpret the binding values, there is simply no possibility of an SQL injection. This is by far the safest (and best performing) approach.
uroc shows an example of using the bind methods with prepared statements.
By the way in Lua SQL there is an undocumented escape function for the sqlite3 driver in conn:escape where conn is a connection variable.
For example with the code
print ("con:escape works. test'test = "..con:escape("test'test"))
the result is:
con:escape works. test'test = test''test
I actually tried that to see what it'd do. Apparently there is also such a function for their postgres driver too. I found this by looking at the tests they had.
Hope this helps.