Sub-Queries in Sybase SQL - sql

We have an application which indexes data using user-written SQL statements. We place those statements within parenthesis so we can limit that query to a certain criteria. For example:
select * from (select F_Name from table_1)q where ID > 25
Though we have discovered that this format does not function using a Sybase database. Reporting a syntax error around the parenthesis. I've tried playing around on a test instance but haven't been able to find a way to achieve this result. I'm not directly involved in the development and my SQL knowledge is limited. I'm assuming the 'q' is to give the subresult an alias for the application to use.
Does Sybase have a specific syntax? If so, how could this query be adapted for it?
Thanks in advance.

Sybase ASE is case sensitive w.r.t. all identifiers and the query shall work:
as per #HannoBinder query :
select id from ... is not the same as select ID from... so make sure of the case.
Also make sure that the column ID is returned by the Q query in order to be used in where clause .
If the table and column names are in Upper case the following query shall work:
select * from (select F_NAME, ID from TABLE_1) Q where ID > 25

Related

Using Regex to determine what kind of SQL statement a row is from a list?

I have a large list of SQL commands such as
SELECT * FROM TEST_TABLE
INSERT .....
UPDATE .....
SELECT * FROM ....
etc. My goal is to parse this list into a set of results so that I can easily determine a good count of how many of these statements are SELECT statements, how many are UPDATES, etc.
so I would be looking at a result set such as
SELECT 2
INSERT 1
UPDATE 1
...
I figured I could do this with Regex, but I'm a bit lost other than simply looking at everything string and comparing against 'SELECT' as a prefix, but this can run into multiple issues. Is there any other way to format this using REGEX?
You can add the SQL statements to a table and run them through a SQL query. If the SQL text is in a column called SQL_TEXT, you can get the SQL command type using this:
upper(regexp_substr(trim(regexp_replace(SQL_TEXT, '\\s', ' ')),
'^([\\w\\-]+)')) as COMMAND_TYPE
You'll need to do some clean up to create a column that indicates the type of statement you have. The rest is just basic aggregation
with cte as
(select *, trim(lower(split_part(regexp_replace(col, '\\s', ' '),' ',1))) as statement
from t)
select statement, count(*) as freq
from cte
group by statement;
SQL is a language and needs a parser to turn it from text into a structure. Regular expressions can only do part of the work (such as lexing).
Regular Expression Vs. String Parsing
You will have to limit your ambition if you want to restrict yourself to using regular expressions.
Still you can get some distance if you so want. A quick search found this random example of tokenizing MySQL SQL statements using regex https://swanhart.livejournal.com/130191.html

Sql Limit clause based in input Parameter

I have been trying to find a solution for a limit-clause based on an input parameter from a Json-File. The current code looks somewhat like this
With myJsonTable (JsonText)
as (
Select JsonText)
Select * from Data
Where...
Limit
Case
WHEN (Select JSON_VALUE(JsonText, '$."Amount"') From myJsonTable is not null
THEN (Select JSON_VALUE(JsonText, '$."Amount"') From myJsonTable)
ELSE (10000000)
END
Which I cant seem to get work. The Output I am getting is
Non-negative integeter value expected in LIMIT clause
Is there a way to cast the select done? Trying different Selects anywhere in the Case clause caused the same error.
Exasol only allows constant expression in the limit clause, so it's not directly possible to specify a select statement that references myJsonTable there.
However, you can workaround this issue by using a approach similar to SQL query for top 5 results without the use of LIMIT/ROWNUM/TOP

Unable to understand query after where clause in postgresql

I have a javaFX application with postgresql as a database , I go through the code . But unable to understand sql query in where clause. here is sql query.
SELECT *
FROM gr_group
WHERE gr_parent_id = ? AND gr_id <> 0
ORDER BY gr_description
You are looking at a parametrized SQL query. The question mark ? you see in the WHERE clause will be filled with an actual parameter coming from a Java variable.
<> (Not Equal To) is an operator. It is same as != operator.
This query will select all the columns from the table gr_group where gr_id is not equal to 0 and gr_parent_id specifies a place holder which will be filled later in the code. This query also orders selected data in the ascending order of column gr_description.

Delete Query inside Where clause

Is there any possibility to write delete query inside Where clause.
Example:
Select ID,Name From MyTable Where ID IN(Delete From MyTable)
It may be crazy, but let me explain my situation. In our reporting tool, we are supporting to enter SQL where query.
We will use our own Select and From Clause query and combine the user's where query input.
Example:
Select ID,Name From MyTable Where ("Query typed by user")
Here, user can type any kind of where query filter..
If he types like ID=100 our final query becomes like this
Select ID,Name From MyTable Where (ID=100)
One of our customer asked us what will happen if anyone type the delete query as where query filter. he feels this may be the security hole..so we have tried that kind of possibility in our dev environment. But the sql returns error for the following query.
Select ID,Name From MyTable Where ID IN(Delete From MyTable)
So finally, my question is, is there any other possibility to write Delete Query inside Where clause or Select clause.. If it possible, how can I restrict it?
Yes. They can run a delete. They can type:
1 = 1; DELETE FROM MY_TABLE;
Or even worse in some ways, (since you should have backups):
1 = 0 UNION SELECT SOCIAL_SECURITY_NUMBER, CREDIT_CARD_NUMBER, OTHER_SENSITIVE_DATA FROM MY_SENSITIVE_TABLE;
Now, in your case its hard to validate. Normally if you are just passing a value to filter on you can use parameterised sql to save yourself. You however also need to let the user select a column. In cases like these, usually we use a drop down to allow the user to select a predefined list of columns and then validate the column name server side. We give the user a text box to enter the value to match and then parameterise that.
It's not quite possible. But he can do something like this :
Select ID,Name From MyTable Where (ID=100); (DELETE FROM MyTable Where 1 = 1)
by using ID=100); (DELETE FROM MyTable Where 1 = 1 instead of ID=100
I believe what your customer is talking about is SQL injection, as long as you have taken appropriate methods to block other queries from running after your select statement is done, then you should have no problem in letting them type whatever it is that you want.
From my experience there is no way to delete anything when you are doing a select statement.
Just make sure you have query terminator characters so they don't write something like the following.
select column1,column2, from myTable where ID in (1,2); delete from my table
this would be a valid worry from your customer if you aren't taking proper steps to prevent sql injection from happening.
You could have your SQL reporting tool just not have update, or delete permission and just have it have Read permission. However, it is up to you guys have you handle your sql injection security.

SQL with LIMIT1 returns all records

I made a mistake and entered:
SELECT * FROM table LIMIT1
instead of
SELECT * FROM table LIMIT 1 (note the space between LIMIT and 1)
in the CLI of MySQL. I expected to receive some kind of parse error, but I was surprised, because the query returned all of the records in the table. My first thought was "stupid MySQL, I bet that this will return error in PostgreSQL", but PostgreSQL also returned all records. Then tested it with SQLite - with the same result.
After some digging, I realized that it doesn't matter what I enter after the table. As long as there are no WHERE/ORDER/GROUP clauses:
SELECT * FROM table SOMETHING -- works and returns all records in table
SELECT * FROM table WHERE true SOMETHING -- doesn't work - returns parse error
I guess that this is a standardized behavior, but I couldn't find any explanation why's that. Any ideas?
Your first query is equivalent to this query using a table alias:
SELECT * FROM yourtable AS LIMIT1
The AS keyword is optional. The table alias allows you to refer to columns of that table using the alias LIMIT1.foo rather than the original table name. It can be useful to use aliases if you wish to give tables a shorter or a more descriptive alias within a query. It is necessary to use aliases if you join a table to itself.
From the SQL lite documentation:
This is why I want DB engine to force the usage of keyword AS for alias names
http://beyondrelational.com/modules/2/blogs/70/posts/10814/should-alias-names-be-preceded-by-as.aspx
SELECT * FROM table LIMIT1;
LIMIT1 This has taken as alias by SQL, cause LIMIT1 is not a reserved literal of SQL.
Something after table name and that is not a reserved keyword always taken as an table alias by SQL.
SELECT * FROM table LIMIT 1;
When you used LIMIT just after the table name, SQL found that as a reserved keyword and worked for it as per the behavior. IF you want to use reserved key words in query It can be done by putting reserved literals in quotes. like..
SELECT * FROM table `LIMIT`;
OR
SELECT * FROM table `LIMIT 1`;
Now all words covered under `` quotes will treated as user defined.
Commonly we did mistake with date, timestamp, limit etc.. keywords by using them as column names.