Case statement is not working on query - sql

I am working on jasper report.I have a table named user I have 2 parameters internal,external .When I use internal then my query needs to show the users where username LIKE '%_#__%.__%' and when I use external then my query needs to show the users where username NOT LIKE '%_#__%.__%'.Like when internal then report will show 2,3,4,5 no row and when external then report will show only one row..My query is
SELECT case
when $P{internal} = 'internal' then
id end as cid,
designation,division_name,pin_no,username FROM application_user where username LIKE
'%_#__%.__%'
else
id end as cid,
designation,division_name,pin_no,username FROM application_user where username NOT LIKE
'%_#__%.__%'
but it is not working
Please let me know If i'm not clear

Projection statements cannot be parameterised in SQL directly (but you can in Dynamic SQL, obviously).
Your test expression should be evaluated in the WHERE block, not SELECT. The SQL you posted is not valid and won't run, so I'm curious how you're getting the results you're seeing.
Try this:
SELECT
id AS cid,
designation,
division_name,
pin_no,
username
FROM
application_user
WHERE
( $P{internal} = 'internal' AND username LIKE '%_#__%.__%' )
OR
( $P{internal} <> 'internal' AND username NOT LIKE '%_#__%.__%' )
Note that this will not necessarily result in the best runtime execution plan because of the different effective query "shape" depending on the parameter value. Ideally you should have two different queries selected by your application code which have the different username predicates.

Related

SQL Query to get all the data from tables when there is no parameter

I am trying to get the whole data when there are no filters selected. I have made an array that contains the selections. In case there are no selections then there will be just '' , i.e. no characters but not null.
SELECT * FROM Skills WHERE person IN ('Technology', 'Drilling');
For example - In this query it will return all required - filtered data. So my array contains Technology and Drilling. In case there is nothing selected by the user as a filter then the query would look like:
SELECT * FROM Skills WHERE person IN ('');
In this case the table is returning nothing in SQL Server. I want it to return everything from the table without any filters.
I would really like to get some help here and maybe some resources that might help me achieve the required thing.
The array is being filled in javascript.
It seems really strange to have a column called person compared to values like "Drilling". But you would do something like:
SELECT *
FROM Skills
WHERE person IN (<whatever>) OR <whatever> = '';
Often NULL is used to mean everything, so that would be:
WHERE person IN (<whatever>) OR <whatever> IS NULL;
And "whatever" might be a delimited string, so this might look like:
WHERE person IN (SELECT s.value FROM string_split(#params) s) OR
#params IS NULL;

Nested SELECT "works" when using nonexistant column - why?

folks, I have the following query in SQLite:
select license, username from check_table where
(
username not in (
select username from Address
)
) order by license, username;
Address is another table. The fun part is: Address has no usernamecolumn!!
Details:
Result: Query finished in 0.004 second(s)
If I modify the username part (e.g. to userrname) I get a no such column error, which is totally fine
it never returns any results, even when I replace username with mail_username (which actually exists) in the sub-select - which is totally strange, because it really should.
Now, my question is: Why don't I get an error here?! And does it have something to do with the fact that I never get any results?
You're selecting username from the check_table, not from the address table.
Try to add aliases and check it out:
select ct.license, ct.username
from check_table as ct
where
(
ct.username not in (
select ct.username
from Address as a
)
) order by ct.license, ct.username;
I bet if you will try to use select a.username... you'll get an error about not existing column.
For this purpose, all the time when you're using multiple tables in the query is good to use aliases.

SQL Injection Method

The Injection Procedures are :
SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;
But, My Question Is how the injection query is working in the sql?
its when you have your query as string in your code, something like this
Query = "SELECT UserId, Name, Password FROM Users WHERE UserId = '" + sUserID + "'"
So you pass sUserID = "ABC' OR 1=1;"
this will be translated like
SELECT UserId, Name, Password FROM Users WHERE UserId = 'ABC' OR 1=1
Since the condition 1=1 is always true, adding it at the end of a WHERE statement renders it irrelevant, and always true, as if the WHERE statement does not exist at all. Thus, the query is always executed, regardless of any other conditions added to the WHERE statement.
In the example you provided, If you allow your users to write down their own userID, they can write 105 or 1=1 in the input fields or in a website's URL address, and since or 1=1 makes UserId=105 useless, and the query will always select the data, hence the SQL injection.

How does union select statement output vulnerable columns

Consider a SQL vulnerable site.
Let the number of columns in the query be 3.
So the statement goes, www.test.com?php.id=-1' union select 1,2,3 --+-
My understanding of this statement is like this.
There are 2 statements
Union is used to join both statements.
(-) is used to null the value of the first statement.
' is used to break the query and input a second statement and --+- is used to comment out the rest of the statement.
Upon inputting this statement, The website displays 2 and 3 as vulnerable columns.
What I don't get is that how a select statement displays the vulnerable columns.
Suppose your back-end code did something like:
sql = "SELECT UserId, UserName, Password from Users where UserID = " + id + " AND password = '" + password + "'"
So it would only return results if the User ID and password matched.
Then "injecting" the code above would result in a SQL statement of
SELECT UserId, UserName, Password from Users
where UserID = -1 union select 1,2,3 --+- AND password = 'anything'
Presumably the UI might then display 1 and 2 in the "username" and "password" fields, identifying them as "vulnerable"
It's a technique used to determine how SQL statements are built in back-end code in order to define a true SQL injection attack to retrieve sensitive data.

Inline table in Oracle SQL

I'm trying to integrate with some software (that I can't modify) that queries a database that I can modify.
I can give this software SQL queries, like so "select username, firstname, lastname from users where username in ?"
The software than fills in the ? with something like ('alice', 'bob'), and gets user information for them.
Thing is, there's another piece of software, which I again can't modify, which occasionally generates users like 'user2343290' and feeds them through to the first piece of software. Of course, it throws errors because it can't find that user.
So the query I want to run is something like this:
select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from create_table(?) t
where create_table generates a table with the rows mentioned in ?, with the first column named column1.
Or alternatively:
select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from _universe_ t where t.column1 in ?
where _universe_ is some fake table that contains possible every value in column1 (i.e. infinitely large).
I've tried select ? from dual, but unfortunately this only worked when ? was something like ('x'), not ('x', 'y').
Keep in mind I can't change the format of how the ? comes out, so I can't do select 'alice' from dual union all select 'bob' from dual.
Anyone know how I could do what I've mentioned, or something else to have a similar effect?
You can turn the delimited string of names into a table type like so:
CREATE TYPE name_tab AS TABLE OF VARCHAR2(30);
/
SELECT * FROM table(name_tab('alice','bob'));
So you would just need to create the type then your example would become:
select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from table(name_tab ?) t
(I'm assuming that the ? is replaced by simple text substitution -- because the IN wouldn't work if it was done as a bind variable -- and that the substituted text includes the parentheses.)
However, I am not sure the result of this will be helpful, since when a list of good usernames is given, you'll now have two result rows for each username, one with the actual information and another with the 'Unknown' values.
A better way to phrase the query might be:
select t.column_value username,
NVL(users.firstname,'Unknown'),
NVL(users.lastname,'Unknown')
from table(name_tab ?) t left join users on users.username = t.column_value
That should give you one row per username, with the actual data if it exists, or the 'Unknown' values if it does not.
You could use a pipelined function:
create type empname_t is table of varchar2(100);
create or replace function to_list(p_Names in string) return empname_t pipelined is
begin
pipe row(p_Names);
return;
end;
select * from table(to_list('bob'))
If you need to split the names (e.g. 'bob,alice'), you could use a function accepting a string and returning a empname_t, e.g. Tom Kyte's in_list, see
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:210612357425
and modify the to_list function to iterate over the collection and pipe each item from the collection.