Create a new temporary local table from the result set data from a SELECT statement - sql

SELECT o_id,first_name,last_name
INTO newoperator
FROM operators
WHERE o_id >5 GROUP BY first_name
syntax error at or near "INTO"
Can anyone help

The operation you are trying to accomplish is creating a table based on another table. The generic term for this in SQL is CTAS -- which stands for CREATE TABLE AS.
Not all databases support this syntax. For instance, SQL Server uses the SELECT INTO syntax.
That is because that is the syntax most commonly used for this across databases:
CREATE TABLE newoperator AS
SELECT DISTINCT o_id, first_name, last_name
FROM operators
WHERE o_id > 5;
Note that I fixed the query so it has some hope of working. In your version, last_name and o_id were not in the GROUP BY, which would generate an error (in almost any database).

Related

SQL injection payload after order by in SQL query

Trying to exploit SQL injection for my assignment. Is it possible to execute delete or drop query after order by in select query without using the semicolon in Postgresql?
This is my sample query:
Select *
from table
order by {sql injection payload}
Without using the semicolon in the payload, can we delete data or drop a table?
https://stackoverflow.com/a/6800585
Do we have similar to this Postgrsql?
I tried
Select * from (delete from table_name returning *) a
But getting sql error as 'syntax error at or near from'
Check this document it says we can bypass forbidden character by CHR()
https://book.hacktricks.xyz/pentesting-web/sql-injection/postgresql-injection
DELETE cannot be put inside a subquery. Nor can DELETE be part of a UNION.
So aside from running a second query (that is, separated by a semicolon), there's almost no way you can do what you describe.
You could invoke a stored procedure or function, if you knew of an existing function that performs a DELETE. Example:
Select *
from table
order by {sql injection payload}
After your payload modifies this query:
Select *
from table
order by SomeFunctionThatDeletes()
Another type which works because you can select from a procedure in PostgreSQL:
Select *
from table
order by id
UNION
Select *
from SomeProcedureThatDeletes()
You can't create the function or procedure with SQL injection, so that routine must exist already, and you would need to know its name and how to call it.
DELETE or DROP TABLE are not the only bad things that can happen from SQL injection. It could be a problem if the query returns data that the current user shouldn't have privilege to see. For example, records about a different user's purchases or medical history.
SQL injection can also be accidental instead of malicious. I would even say that most instances of SQL injection result in simple errors instead of data breaches. Those aren't really attacks, but they lead to an unsatisfactory experience for your users.

Sub-Queries in Sybase 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

Why does MAX(Column) as Column give error, and MAX(Column) as max_Column does not?

I was just wondering, why does:
select max(run_id) as run_id from my_table where run_id > 50;
It gives an error and
select max(run_id) as max_run_id from my_table where run_id > 50;
select max(run_id) from my_table where run_id > 50;
the above two queries does not give an error.
Let's say the structure of the table is,
create table my_table(
run_id int,
something varchar(10))
This table has 100 run_id's.
I know you can't use where clause with aggregate functions.
Is it because we rename the column (as max_run_id) and the sql is treating it as a separate column, where if the name was the same as the original column it sees the aggregate function and gives the error because of it? Or can someone explain that with better terms.
Indeed, this should work (and it works in other DBMS-s, like SQL Server, Oracle, MySQL, etc). You could say it's a bug in Sybase IQ or (more accurately) a non-standard implementation.
It seems that Sybase IQ allows using aliases anywhere in the query, because the documentation says: "alias-names can be used throughout the query to represent the aliased expression. [...] If you use the same name or expression for a column alias as the column name, the name is processed as an aliased column, not a table column name.
The error message indicates that "a SELECT statement cannot contain an aggregate function within a predicate in the WHERE clause"
In other words, Sybase IQ understands your query as:
select max(run_id) as run_id from my_table where max(run_id) > 50;

Rowcounts of all tables in a database in Netezza

I am migrating data from MS SQL to Netezza and so I need to find the row counts of all tables in a database (in Netezza). Any query for the same would be of an immense help to me as I'm completely new to this. Thanks in advance.
This query does it directly from _v_table:
SELECT TABLENAME, RELTUPLES FROM _V_TABLE where objtype = 'TABLE' ORDER BY RELTUPLES
something like this should work:
select 'select '||chr(39)||tablename||chr(39)||' as entity, count(1) from '||tablename||' union all'
from _v_table
where object_type ='TABLE';
copy/paste the result, remove the last "union all".
I have never used Netezza but googled and found:
http://www.folkstalk.com/2009/12/netezza-count-analytic-functions.html
SELECT dept_id,
salary,
COUNT(1) OVER() total_cnt
FROM Employees
If you don't know what tables that exists:
http://www.folkstalk.com/2009/11/netezza-system-catalog-views.html
select * from _v_table;
Another way to acquire the row counts for a table (if you have access to the operating system level) is to use the Netezza nz_get_table_rowcount command. You can enter, "nz_get_table_rowcount -h" to get all of the help text on this command, but the format is:
Usage: nz_get_table_rowcount [database]
Purpose: Perform a "SELECT COUNT(*) FROM ;" to get its true rowcount.
Thus, this script results in a full table scan being performed.
Inputs: The database name is optional. If not specified, then $NZ_DATABASE
will be used instead.
The table name is required. If only one argument is specified, it
will be taken as the table name.
If two arguments are specified, the first will be taken as the
database name and the second will be taken as the table name.
Outputs: The table rowcount is returned.
Use this command in a shell script to cycle through all of the tables within a database. Use nz_get_table_names to get the list of tables within a database.

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.