Why can't I use an alias in a DELETE statement? - sql

In SQL Server Compact Edition in Visual Studio 2010 (maybe SQL Server and SQL in general, I don't know), this command works:
DELETE FROM foods WHERE (name IN ('chickens', 'rabbits'))
but this command produces an error of: Error near identifier f. Expecting OUTPUT.
DELETE FROM foods f WHERE (f.name IN ('chickens', 'rabbits'))

To alias the table you'd have to say:
DELETE f FROM dbo.foods AS f WHERE f.name IN (...);
...though I fail to see the point of aliasing for this specific statement, especially since (at least IIRC) this no longer conforms to strict ANSI, may cause unnecessary hurdles when writing for multiple platforms, and it introduces complexity and confusion for new users learning the basics of vanilla DML.
This will do and doesn't require an alias:
DELETE dbo.foods WHERE name IN (...);
But yes, as comments suggest, it may be necessary for other query forms (e.g. any DML combined with correlation, joins, EXISTS, etc). In SQL Server you can do this using, for example:
DELETE f
FROM dbo.foods AS f
INNER JOIN dbo.allergies AS a
ON f.FoodId = a.FoodId;
Just keep in mind this query may have to be constructed differently on {not SQL Server}.

The delete statement has strange syntax. It goes like this:
DELETE f FROM foods f WHERE (f.name IN ('chickens', 'rabbits'))

Related

Is SELECT INTO T-SQL?

I'm working in a project where I have been explicitly required to not use T-SQL syntax. The application we are using supports T-SQL but we are not allowed to use it to avoid potential migration issues.
My question is: is the SELECT ... INTO statement T-SQL or SQL? If it is T-SQL, is there a specific SQL query to copy an existing table into a new one? (I have tried with CREATE TABLE AS .. FROM but it doesn't work).
Sounds like a very basic question but I haven't been able to find the answer anywhere. Thus, in addition to the question above, it would be very helpful to know if there is a guide/dictionary/website that collects only the standard SQL syntax.
Thanks!
I think they recommend you to use ANSI SQL, instead of T-SQL (SQL Server) or PL-SQL (ORACLE). Considering it as common requirement, every database vendor provide their own way of implementing this requirement. When you use ANSI SQL, you will not have migration issues, when you move from one database vendor to another database vendor.
SQL SERVER
SELECT * INTO new_table
FROM existing_table
ORACLE & ANSI-SQL
CREATE TABLE new_table
AS SELECT * FROM existing_table
is SELECT INTO TSQL or SQL?
Neither. The MySQL documentation claims that SELECT INTO is a Sybase extension to standard sql. As such I don't think you can accurately say it's either of these, but you can say that it's neither. It is indeed used in T-SQL, as well as some other database vendor products, to create a table from a query. The SQL standard says that queries with that goal should be formed as CREATE TABLE blah AS SELECT .... Oracle/MySQL, for example, use the standard form though you can see them use SELECT INTO in a different context, to assign data to variables in stored procedures
If you want to avoid use of this non standard syntax when creating and populating a table then you'll have to:
CREATE TABLE blah (column spec to match query output)
INSERT blah (select query here)
But then you run into nuances like "sqlserver calls it datetime/datetime2 but oracle calls it date/timestamp"
And ultimately you'll probably get into a situation where you just can't use one form of sql to do all you want..
I'd imagine most libraries that do data access on multiple underlying databases have mechanisms to use vendor specific terminology where required
From the answers, it appears you might need to specify which SELECT INTO you're talking about. The other answers seem to suggest there exists some kind of SELECT ... INTO <table-name> when there is also a kind of SELECT ... INTO <local-variable-name list>. The latter is used in embedded SQL for making SQL interact with variables of the host language program. I'm not certain but that variant may also be used in the part of the SQL language that deals with procedures written in SQL (the SQL/PSM part of the standard).
A "reference" that covers "only the standard SQL syntax" is, in principle, the ISO standard document itself, only available by purchase from ISO (and yes, it's ISO not ANSI - ANSI does nothing more than rubberstamping the ISO document after removing all the names of non-US contributors). And not the easiest kind of literature. There are "draft" versions floating around on the internet that might deviate from the published final standards. E.g. http://www.wiscorp.com/sql200n.zip. Note that this is a SQL:2008 draft. Current standard version is SQL:2011. And it's several thousands of pages, so I guess that covers your question "Is all the syntax covered in w3schools standard SQL". (Hint : no)

What is the best way to find DML references to objects in SQL Server?

Something I have always struggled with is finding DML references to tables in SQL server at the company I work. We have our code held in TFS source control and deployed to a shared development environment so I can search using either file searching or t-sql code. The challenge I have is that I can easily find all references to a table name but I can't find a good way to filter further to a particular statement like UPDATE/INSERT/MERGE.
A large challenge in this is that the company I work at has a lot of dynamic SQL so I think the best method will be some form of text searching. The other challenge is that coding is written as each developer sees fit so an UPDATE statement will not be written in any 'standard' way throughout the code base - i.e. the table name could be on the same line as the DML statement or on a separate line.
I have been able to use some basic regular expression searching in Visual Studio to find instances where the keyword is on the same line as the table name but I don't know how to search for it being 'close'.
Has anybody else faced this issue and found a good way to search for this information? What I would love is a tool where you put in a t-sql reserved keyword and an object name and the tool shows you all references.
One way to at least see all the code across Views, SP, Functions, etc is to run this:
--will show you all source code from procs, views, functions etc
select *
from syscomments
--or better to join it on sysobjects and display only view source code for example
select o.id,o.name,c.text
from syscomments c
inner join sysobjects o on o.id = c.id
where o.[Type] = 'V'
I found once I have all of this, I can then do easy searching in Excel or via Notepad++.
I hope that helped.

SQL join using USING: <column name> is not a recognized table hints option

I have the following JOIN:
SELECT * FROM tableA INNER JOIN tableB USING (commonColumn)
I get an error:
"commonColumn" is not a recognized table hints option. If it is
intended as a parameter to a table-valued function or to the
CHANGETABLE function, ensure that your database compatibility mode is
set to 90.
The following instead works:
SELECT * FROM tableA INNER JOIN tableB ON tableA.commonColumn = tableB.commonColumn
The compatibility level in my case is set to 100 (SQL Server 2008), while, by the way, I am working with SQL Server 2012.
What am I doing wrong? I find it very difficult to find example of the use of the keyword USING, as it is almost impossible to do a relevant web search. Yet, it seems the right thing to use when the "joining columns" have the same name...
USING is not supported SQL Server syntax. It's not a reserved keyword, either, so the query engine is using that as a table alias.
It is an ODBC keyword, but those are handled somewhat differently. The engine won't always complain if you use them, but you're not supposed to use them anyways.
It is also listed as a possible future reserved keyword. It's common for new editions of SQL Server to add words to the core reserved list.
Personally, I don't see them adding NATURAL JOIN syntax support, even with USING. A lot of DBAs consider NATURAL JOINs problematic.
The USING keyword is used to specify the source data for MERGE statements (called <table source>) in the documentation.

Stored procedure dependencies in SQL Server Management Studio

I don't know much about the MS world, but now it happens to be that I have to use SQL Server Management Studio 2008.
My problem: I have a column in a table, and I need to see all the stored procedures that may be acting on it.
I tried right-clicking and going 'View Dependencies' but that doesn't seem to be returning everything that it should be.
Questions like this one: SQL Server Dependencies have answers that offer 3 types of solutions
Paid third party tools.
Writing your own scripts.
Exporting everything into text files and grepping them.
WTF? Am I missing something obvious? Is that actually how things work? I would imagine that this is a very common use case: you want to alter table and you want to make sure you won't break anything. Or if say you're looking at a new project with a DB for the first time and you want to see how certain columns get populated with stored procedures. Is there actually no quick and easy built-in workflow to do this?
If you need to find database objects (e.g. tables, columns, triggers) by name - have a look at the FREE Red-Gate tool called SQL Search which does this - it searches your entire database for any kind of string(s).
It's a great must-have tool for any DBA or database developer - did I already mention it's absolutely FREE to use for any kind of use??
Use this query:
SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%YOUR COLUMN %'
AND ROUTINE_TYPE='PROCEDURE'
I have spent a good amount of time trying to find a way to identify column level dependencies in a quick way without having to search text or use third party applications. The other challenge is finding dependencies across multiple databases where table names may repeat, which will cause false positives when searching SP text.
As of SQL 2008, there is a function that returns dependencies across databases on a field level.
The code below works with a few exceptions:
It will fail if there are stored procedures with invalid references on tables/fields that have been deleted (Incidently I found this to be useful to find SPs that had been accidentally broken by table modifications).
It doesn't find all dependencies in cases where the SP is using temp tables in unusual ways.
In some cases I found that it was returning false positives for complex stored procedures.
MSDN Documentation
This code should be run from within the database where the SP is in order to be able to cross to other database dependencies.
SELECT
--SP, View, or Function
ReferencingName = o.name,
ReferencingType = o.type_desc,
--Referenced Field
ref.referenced_database_name, --will be null if the DB is not explicitly called out
ref.referenced_schema_name, --will be null or blank if the DB is not explicitly called out
ref.referenced_entity_name,
ref.referenced_minor_name
FROM sys.objects AS o
cross apply sys.dm_sql_referenced_entities('dbo.' + o.name, 'Object') ref
where o.type in ('FN','IF','V','P','TF')
I wonder why you cannot see the dependencies via the 'View Dependencies' dialog because it works perfectly fine for me. Nevertheless you can query the 'sys.sql_expression_dependencies' system view and obtain the dependency information that you want.
Example
SELECT OBJECT_NAME(referencing_id),OBJECT_NAME(referenced_id)
FROM sys.sql_expression_dependencies
WHERE referenced_id = OBJECT_ID('XXX')
You can of course project other information that you might need.
List of All Dependent Objects in single query.
select distinct A.name from sys.procedures A inner join sys.sql_dependencies B
on A.object_id = B.object_id;
OR
select distinct A.name from sys.objects A inner join sys.sql_dependencies B
on A.object_id = B.object_id where A.type_desc = 'mentioned your Object Type';

Access DB update one table with value from another

I'm trying to update all records in one table with the values found in another table.
I've tried many versions of the same basic query and always get the same error message:
Operation must use an updateable
query.
Any thoughts on why this query won't work in Access DB?
UPDATE inventoryDetails as idet
SET idet.itemDesc =
(
SELECT bomItemDesc
FROM BOM_TEMPLATES as bt
WHERE bt.bomModelNumber = idet.modelNumber
)
also tried this because I realized that since the second table has multiple model number records for each modelnumber - and I only need the first description from the first record found for each model number.
UPDATE inventoryDetails as idet
SET idet.item_desc =
(
SELECT TOP 1 bomItemDescription
FROM BOM_TEMPLATES as bt
WHERE bt.bomModelNumber = idet.modelNumber
)
...still getting the same error though.
You have to use a join
UPDATE inventoryDetails
INNER JOIN BOM_TEMPLATES ON inventoryDetails.modelNumber = BOM_TEMPLATES.bomModelNumber
SET inventoryDetails.itemDesc = [bomItemDesc];
Any thoughts on why this query won't work in Access DB?
The answer is, because ACE/Jet SQL syntax is not SQL-92 compliant (even when in its ANSI-92 Query Mode!).
I'm assuming yours is a scalar subquery. This construct is simply not supported by ACE/Jet.
ACE/Jet has its own quirky and flawed UPDATE..JOIN syntax, flawed because the engine doesn't force the JOINed values to be scalar and it is free to silently use an arbitrary value. It is different again from SQL Server's own UPDATE..JOIN syntax but at least SQL Server supports the Standard scalar subquery as an alternative. ACE/Jet forces you to either learn its quirky non-portable ways or to use an alternative SQL product.
Sorry to sound negative: the ACE/Jet engine is a great piece of software but UPDATE syntax is absolutely fundamental and the fact it hasn't been changed since the SQL-92 Standard really show its age.
try:
update idet
SET idet.itemDesc = bt.bomItemDesc
from inventoryDetails as idet
inner join BOM_TEMPLATES as bt
on bt.bomModelNumber = idet.modelNumber
This is how I would write it for SQL server. Hope Access understands the same command.