I have seen many functions, on every function I see they have parenthesis() on its end like,
SELECT SCOPE_IDENTITY();
SELECT IDENT_CURRENT('TableName');
But why some function's do not use with parenthesis() like function
SELECT ##IDENTITY;
##xxxxx are system functions without parameters which should be treated as read-only variables
I believe that these used to be referred to as "server variables" and so had a "variable-like" syntax rather than a function syntax. They have since been re-defined as functions, but maintain the older syntax for backwards-compatibility.
Unfortunately, I cannot find any online resources presently to back-up this claim, and I think the "server variables" definition had been retired by the 2000 release of the product.
If we take the example of ##ROWCOUNT. In SQL Server 2000 BOL, it's described as:
Returns the number of rows affected by the last statement.
...
This variable is set...
(My emphasis).
Compare that with the current documentation, which refers to it having its value set but now avoids referring to it as a variable (or a function). And, of course, it's modern, enhanced, doesn't have to support backwards compatibility sibling ROWCOUNT_BIG which has normal function syntax. And is explicitly referred to as a function.
I do not believe that Microsoft have introduced any new functions using the ## variable syntax since before 2000 was released.
Related
I've found that over the years my habits have changed and I much prefer writing queries like this:
select FriendlyName = some_column from some_table
as opposed to this:
select some_column as FriendlyName from some_table
Lately I've been reviewing scripts written by some SQL experts which were designed to work across multiple database versions and platforms and I only ever see the latter syntax.
This was never a concern for me before as a software developer knowing specifically what version of SQL Server my code would be run on, but now I'm writing code that I would like to make as accessible to as many versions/platforms as possible. At least, I'd like to write it so the least amount of modifications are necessary to run on additional versions when the time comes.
That said, my question is whether the former syntax (alias = some_column) has always been part of the SQL specification and will run on any database, or would it not work in some platforms or older versions?
The alias = syntax is specific to SQL Server. The standard is either:
<expression> as alias
<expression> alias
That is, the as is optional -- although I strongly encourage using it.
It is a shame that you have adapted to a syntax that is not available in other databases, and can actually mean other things. In most other databases that accept the syntax, it will be interpreted as a boolean comparison -- and often generate an error because alias is not defined.
And, unfortunately, this syntax convention makes it harder to SQL Server to support a real boolean type, which would be a convenience.
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)
From a great reply:
in PostgreSQL, CREATE FUNCTION is indeed a "SQL statement" but is is merely a
"wrapper" to specify a block of code that is executed by something
different than the SQL query "engine". Postgres (unlike other DBMS)
supports multiple "runtime engines" that can execute the block of code
that was passed to the "CREATE FUNCTION" statement - one artifact of
that is that the code is actually a string so CREATE FUNCTION only
sees a string, nothing else.
What are the consequences of "the code is actually a string so CREATE FUNCTION only sees a string, nothing else"?
Is that considered as dynamic SQL? Does it prevent or introduce SQL injection risk, compared to dynamic SQL?
How is that different from other RDBMS (if any?) where "the code is not a string"?
Thanks.
PostgreSQL is highly extensible, and you can for example define your own procedural language to write functions in.
PostgreSQL knows nothing about the language except that it has to call a certain language handler to execute the function.
The way that was chosen to implement this is to simplify pass the code as a string.
This is just an implementation detail and does not make PostgreSQL functions any more or less vulnerable to SQL injection than other RDBMS.
There are several levels on which you have to defend yourself against injection:
The function arguments: Here you should choose non-string data types whenever possible.
The SQL statements within the function: Here you should avoid dynamic SQL whenever possible, and if you have to use dynamic SQL, you should insert variables using the %L pattern of the format function.
Again, this is the same if function bodies are specified as strings or not.
All 3GL+ code is basically a string. The "parameter" passed to CREATE FUNCTION is code (to be executed outide the core SQL engine), which is a string (that's not SQL).
Other RDMS's only support SQL as the function/procedure body.
I have a SqlServer db that I would like to port to MySQL. What's the best way to to this. Things that need to be ported are:
Tables (and data)
FileStream → MySQL equivalent?
Stored Procedures
Functions
Data types are relatively similar.
There is no equivalent to FileStream in MySQL - the files must either be stored as BLOBs, or on the file system while the path is stored in the database.
Migrating away from TSQL means:
There's no WITH clause in MySQL - it will have to converted into a derived table/inline view
There's no TOP syntax - these have to be converted to use LIMIT
There's no ranking/analytic functionality in MySQL - can't use ROW_NUMBER, RANK, DENSE_RANK or NTILE. See this article for alternatives.
MySQL views have notoriously limited functionality:
The SELECT statement cannot contain a subquery in the FROM clause.
The SELECT statement cannot refer to system or user variables.
Within a stored program, the definition cannot refer to program parameters or local variables.
The SELECT statement cannot refer to prepared statement parameters.
Any table or view referred to in the definition must exist. However, after a view has been created, it is possible to drop a table or view that the definition refers to. In this case, use of the view results in an error. To check a view definition for problems of this kind, use the CHECK TABLE statement.
The definition cannot refer to a TEMPORARY table, and you cannot create a TEMPORARY view.
Any tables named in the view definition must exist at definition time.
You cannot associate a trigger with a view.
As of MySQL 5.0.52, aliases for column names in the SELECT statement are checked against the maximum column length of 64 characters (not the maximum alias length of 256 characters).
Dynamic SQL will have to be converted to use MySQL's Prepared Statement syntax
A guide/article with some useful tips is available on the official MySQL dev site.
This is not for the faint of heart. Here is an article that explains what you are in for:
http://searchenterpriselinux.techtarget.com/news/column/0,294698,sid39_gci1187176,00.html
I'm working on a legacy product and i have some SQL being executed through ADO, to an Access database with linked tables to SQL Server. I'm getting the error 'Undefined function 'Round' when i execute the SQL but if i take the query and run directly in Access it works fine. I know that EVERYTHING is correct and that this is a machine specific issue since this is production code, it works on other machines and has been deployed successfully for many clients.
I'm not even sure where to begin to be honest. I'm running the correct (latest) versions of Jet/ADO/MDAC.
ANY help would be appreciated.
Thanks in advance.
EDIT: Obviously, the SQL includes the aggregate function 'Round'. I'm aware of the differences between Jet and SQL implementations. This problem is due to some problem with a component on my machine and NOT with the code. The SQL executes properly when done through MS Access 2007 but NOT through ADO.
EDIT2: Right solution from the comments:
shahkalpesh: If it executes fine thru Access, it could be that Access has the DLL available to it, which has the Round function. What is the connection string, you are using?
Stimul8d: I'm not sure how it can be anything so do with the connection string. This code works on EVERY other machine, with no changes; just not on mine.
Andomar: Well, that's your problem right there, your machine is farked up. You can still install vb6 sp6 maybe.
Stimul8d: Well, SP6 fixed it. Cheers Anndomar, no idea why SP6 fixed it but it did!
EDIT: Based on your comment this newsgroup post might be the answer:
Unfortunately, when you are running
queries from outside of Access (as you
are from VB), your only connection to
the database is through the Jet
engine, which doesn't know anything
about most VBA functions. There's no
way around this, other than to return
the data to your VB application and
use the functions on the data there.
And two posts later:
I solved the problem. Updated my VB
with the Service Pack 6... it took
care of the problems.
Old answer here:
Try FLOOR() instead of ROUND().
To round something to the nearest integer, you could:
declare #floatmyboat float
set #floatmyboat = 1.51
select floor(#floatmyboat+0.5)
P.S. Maybe post the exact error you get. If it's "The round function requires 2 to 3 arguments.", that means Sql Server is borking on the ROUND().
The round() function exists in SQL Server as well.
The only difference is: in Access the precision is an optional parameter, but in SQL Server you have to specify it.
So this will only work in Access, but not in SQL Server:
select round(Column) from Table
This will work in Access and SQL Server:
select round(Column,1) from Table
it could be that Access has the DLL
available to it, which has the Round
function
ACE/Jet uses share expression services with VBA. Broadly speaking, ACE/Jet supports as expressions all VBA5 functions (as distinct from methods) whose arguments and return values are scalar types (e.g. no arrays, no objects). The Round() expression falls into this definition and indeed is available to ACE/Jet with the same semantics as its VBA function equivalent. As anyone familiar with the ACE/Jet engine should know, though, the semantics can differ from the VBA equivalents e.g. ACE/Jet ANSI-92 Query Mode SQL
SELECT TYPENAME(ROUND(5, 1))
returns 'Long', whereas VBA
?Typename(Round(5, 1))
returns 'Integer'.
In other words, Round() wasn't going to be the problem here.