SQL Server : Table instead of very complex view - sql

Normally a full table from a view is created by:
SELECT *
INTO dbo.table
FROM view
But I have a very complex view (which worked in SQL Server 2005), but in SQL Server 2008 Express, I get the error message:
Internal error: An expression services limit has been reached. Please
look for potentially complex expressions in your query, and try to
simplify them.
By eliminating the header <CREATE VIEW viewname AS> I managed to do a normal query.
So I want to copy this query into a new table with all columns of the query.
The query (or the view) consists of 3 tables with a lot of joins and so on.
My question is, how is it possible to get my problem solved?
SELECT *
INTO dbo.table
FROM <here is my complex query, beginning with select>
does not work.

Do it in two steps :
First create your table with the appropriate column names and type.
Use then an INSERT INTO .... SELECT statement like this :
INSERT INTO yourNewTable
(column1,
column2,
...
)
SELECT (your complex query)
Explicitely listing the columns is not mandatory if the result of your query directly match the structure of your target table. Nonetheless it is still advised for maintenability reasons.

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.

SQL: temp table "invalid object name" after "USE" statement

I do not fully understand the "USE" statement in Transact-SQL and how it affects the scope of temp tables. I have a user-defined table type in one database but not another, and I've found I need to "USE" that database in order to define a table of that type. Earlier in the query, I define a temporary table. After the "USE" statement, SSMS does not recognize the temp table as a valid object name, however I can still query from it without error.
The skeleton of my SQL query is as follows:
USE MYDATABASE1
[... a bunch of code I did not write...]
SELECT * INTO #TEMP_TABLE FROM #SOME_EARLIER_TEMP_TABLE
USE MYDATABASE2
DECLARE #MYTABLE MyUserDefinedTableType -- this table type only exists in MYDATABASE2
INSERT INTO #MYTABLE(Col1, Col2)
SELECT Col1, Col2 FROM (SELECT * FROM MYDATABASE2.dbo.SOME_TABLE_VALUED_FUNCTION(param1, param2)) T
SELECT A.*, B.Col2
FROM #TEMP_TABLE A
CROSS APPLY DATABASE2.dbo.SOME_OTHER_TABLE_VALUED_FUNCTION(#MYTABLE, A.SomeColumn) B
In the last SELECT statement, SSMS has red squiggly lines under "A.*" and "#TEMP_TABLE", however there is no error running the query.
So my question is: am I doing something "wrong" even though my query still works? Assuming the initial "USE MYDATABASE1" is necessary, what is the correct way to switch databases while still having #TEMP_TABLE available as a valid object name? (Note that moving the definition of #TEMP_TABLE to after "USE MYDATABASE2" would just shift the problem to #SOME_EARLIER_TEMP_TABLE.)
In SQL USE basically tells the query which database is the "default" database.
Temp tables can play tricks on intellisense - unless they're explicitly defined using the CREATE TABLE #MyTempTable route, intellisense doesn't really know what to do with them a lot of the time. Don't worry though - temp tables are scoped to the query.
Although I do feel it's worth pointing out: while UDTs are database specific, you can create an assembly to use across databases

Drop tables using table names from a SELECT statement, in SQL (Impala)?

How do I drop a few tables (e.g. 1 - 3) using the output of a SELECT statement for the table names? This is probably standard SQL, but specifically I'm using Apache Impala SQL accessed via Apache Zeppelin.
So I have a table called tables_to_drop with a single column called "table_name". This will have one to a few entries in it, each with the name of another temporary table that was generated as the result of other processes. As part of my cleanup I need to drop these temporary tables whose names are listed in the "tables_to_drop" table.
Conceptually I was thinking of an SQL command like:
DROP TABLE (SELECT table_name FROM tables_to_drop);
or:
WITH subquery1 AS (SELECT table_name FROM tables_to_drop) DROP TABLE * FROM subquery1;
Neither of these work (syntax errors). Any ideas please?
even in standard sql this is not possible to do it the way you showed.
in standard sql usually you can use dynamic sql which impala doesn't support.
however you can write an impala script and run it in impala shell but it's going to be complicated for such task, I would prepare the drop statement using select and run it manually if this is one-time thing:
select concat('DROP TABLE IF EXISTS ',table_name) dropstatements
from tables_to_drop

SQL: how to find a mapping of view columns to table columns?

In Microsoft SQL Server 2008 R2, let's say my database has the following view:
create view [dbo].[MyView]
(
[MyColumnA]
)
AS
(SELECT MyColumnB FROM MyTable)
Now let's suppose I only know that there is a view called MyView that has a column called MyColumnA, but I don't know that it maps to MyTable.ColumnB. What is the easiest/fastest way to determine which table and column MyView.ColumnA maps to? Is there a query that can tell me this? Something like:
SELECT TABLE_NAME, TABLE_COLUMN_NAME
FROM INFORMATION_SCHEMA.VIEW_MAPPINGS
WHERE VIEW_NAME = 'MyView' AND VIEW_COLUMN_NAME = 'MyColumnA'
This query would return [MyTable, MyColumnB].
Currently I have to find the view in SSMS Object Explorer, right click it and generate the create script, then search for the name of the view's column. Then I note which ordinal position it is in the view (let's say 4th column), and have to find the corresponding 4th column in the select statement. The select statement will most likely be using a table alias, so then I have to look through the JOIN statements to find the table name based on the alias.
This is quite time consuming, and I'm hoping to find a faster way, if not by a query then perhaps by some other process that is faster or easier than mine.
SP_DEPENDS should work
SP_DEPENDS 'MyView'

Operation must use an updatable query. (Error 3073)

I have written this query:
UPDATE tbl_stock1 SET
tbl_stock1.weight1 = (
select (b.weight1 - c.weight_in_gram) as temp
from
tbl_stock1 as b,
tbl_sales_item as c
where
b.item_submodel_id = c.item_submodel_id
and b.item_submodel_id = tbl_stock1.item_submodel_id
and b.status <> 'D'
and c.status <> 'D'
),
tbl_stock1.qty1 = (
select (b.qty1 - c.qty) as temp1
from
tbl_stock1 as b,
tbl_sales_item as c
where
b.item_submodel_id = c.item_submodel_id
and b.item_submodel_id = tbl_stock1.item_submodel_id
and b.status <> 'D'
and c.status <> 'D'
)
WHERE
tbl_stock1.item_submodel_id = 'ISUBM/1'
and tbl_stock1.status <> 'D';
I got this error message:
Operation must use an updatable query. (Error 3073) Microsoft Access
But if I run the same query in SQL Server it will be executed.
Thanks,
dinesh
I'm quite sure the JET DB Engine treats any query with a subquery as non-updateable. This is most likely the reason for the error and, thus, you'll need to rework the logic and avoid the subqueries.
As a test, you might also try to remove the calculation (the subtraction) being performed in each of the two subqueries. This calculation may not be playing nicely with the update as well.
Consider this very simple UPDATE statement using Northwind:
UPDATE Categories
SET Description = (
SELECT DISTINCT 'Anything'
FROM Employees
);
It fails with the error 'Operation must use an updateable query'.
The Access database engine simple does not support the SQL-92 syntax using a scalar subquery in the SET clause.
The Access database engine has its own proprietary UPDATE..JOIN..SET syntax but is unsafe because, unlike a scalar subquery, it doesn’t require values to be unambiguous. If values are ambiguous then the engine silent 'picks' one arbitrarily and it is hard (if not impossible) to predict which one will be applied even if you were aware of the problem.
For example, consider the existing Categories table in Northwind and the following daft (non-)table as a target for an update (daft but simple to demonstrate the problem clearly):
CREATE TABLE BadCategories
(
CategoryID INTEGER NOT NULL,
CategoryName NVARCHAR(15) NOT NULL
)
;
INSERT INTO BadCategories (CategoryID, CategoryName)
VALUES (1, 'This one...?')
;
INSERT INTO BadCategories (CategoryID, CategoryName)
VALUES (1, '...or this one?')
;
Now for the UPDATE:
UPDATE Categories
INNER JOIN (
SELECT T1.CategoryID, T1.CategoryName
FROM Categories AS T1
UNION ALL
SELECT 9 - T2.CategoryID, T2.CategoryName
FROM Categories AS T2
) AS DT1
ON DT1.CategoryID = Categories.CategoryID
SET Categories.CategoryName = DT1.CategoryName;
When I run this I'm told that two rows have been updated, funny because there's only one matching row in the Categories table. The result is that the Categories table with CategoryID now has the '...or this one?' value. I suspect it has been a race to see which value gets written to the table last.
The SQL-92 scalar subquery is verbose when there are multiple clauses in the SET and/or the WHERE clause matches the SET's clauses but at least it eliminates ambiguity (plus a decent optimizer should be able to detects that the subqueries are close matches). The SQL-99 Standard introduced MERGE which can be used to eliminate the aforementioned repetition but needless to say Access doesn't support that either.
The Access database engine's lack of support for the SQL-92 scalar subquery syntax is for me its worst 'design feature' (read 'bug').
Also note the Access database engine's proprietary UPDATE..JOIN..SET syntax cannot anyhow be used with set functions ('totals queries' in Access-speak). See Update Query Based on Totals Query Fails.
Keep in mind that if you copy over a query that originally had queries or summary queries as part of the query, even though you delete those queries and only have linked tables, the query will (mistakenly) act like it still has non-updateable fields and will give you this error. You just simply re-create the query as you want it but it is an insidious little glitch.
You are updating weight1 and qty1 with values that are in turn derived from weight1 and qty1 (respectively). That's why MS-Access is choking on the update. It's probably also doing some optimisation in the background.
The way I would get around this is to dump the calculations into a temporary table, and then update the first table from the temporary table.
There is no error in the code. But the error is Thrown because of the following reason.
Please check weather you have given Read-write permission to MS-Access database file.
The Database file where it is stored (say in Folder1) is read-only..?
suppose you are stored the database (MS-Access file) in read only folder, while running your application the connection is not force-fully opened. Hence change the file permission / its containing folder permission like in C:\Program files all most all c drive files been set read-only so changing this permission solves this Problem.
In the query properties, try changing the Recordset Type to Dynaset (Inconsistent Updates)