What exactly does the T-SQL "LineNo" reserved word do? - sql-server

I was writing a query against a table today on a SQL Server 2000 box, and while writing the query in Query Analyzer, to my surprise I noticed the word LineNo was converted to blue text.
It appears to be a reserved word according to MSDN documentation, but I can find no information on it, just speculation that it might be a legacy reserved word that doesn't do anything.
I have no problem escaping the field name, but I'm curious -- does anyone know what "LineNo" in T-SQL is actually used for?

OK, this is completely undocumented, and I had to figure it out via trial and error, but it sets the line number for error reporting. For example:
LINENO 25
SELECT * FROM NON_EXISTENT_TABLE
The above will give you an error message, indicating an error at line 27 (instead of 3, if you convert the LINENO line to a single line comment (e.g., by prefixing it with two hyphens) ):
Msg 208, Level 16, State 1, Line 27
Invalid object name 'NON_EXISTENT_TABLE'.
This is related to similar mechanisms in programming languages, such as the #line preprocessor directives in Visual C++ and Visual C# (which are documented, by the way).
How is this useful, you may ask? Well, one use of this it to help SQL code generators that generate code from some higher level (than SQL) language and/or perform macro expansion, tie generated code lines to user code lines.
P.S., It is not a good idea to rely on undocumented features, especially when dealing with a database.
Update: This explanation is still correct up to and including the current version of SQL Server, which at the time of this writing is SQL Server 2008 R2 Cumulative Update 5 (10.50.1753.0) .

Depending on where you use it, you can always use [LineNo]. For example:
select LnNo [LineNo] from OrderLines.

Related

Error in the sentence "unload" using Informix

I try to use this sentence "unload" in Informix but it doesn't work:
UNLOAD TO 'p7024cargaP.unl' select * from p7024carga;
[Error] Script lines: 1-4 --------------------------
A syntax error has occurred.
Script line 1, statement line 1, column 1
So maybe it is because I am using this sentence in Aqua Data Studio.
I have a Windows system in my pc. Can someone help me?
UNLOAD is not a command understood by the server. Some tools, notably DB-Access, recognize the syntax and use a more or less complex sequence of operations to declare a cursor for the SELECT statement and then open the cursor, fetch each row, and format the result, writing to the named file.
Your primary option is to use DB-Access to execute the statement. That is certainly the simplest.

What is regexp_replace equivalent in SQL Server

I have this piece of code in Oracle which I need to convert into SQL Server to get the same behavior. I have used the REPLACE function. It seems to be working but I just wanted to make sure.
REGEXP_REPLACE(
phonenumber,
'([[:digit:]]{3})([[:digit:]]{3})([[:digit:]]{4})',
'(\1)\2-\3'
) phonenumber
As Martin said in his answer, SQL Server does not have built-in RegEx functionality (and while it has not been suggested here, just to be clear: no, the [...] wildcard of LIKE and PATINDEX is not RegEx). If your data has little to no variation then yes, you can use some combination of T-SQL functions: REPLACE, SUBSTRING, LEFT, RIGHT, CHARINDEX, PATINDEX, FORMATMESSAGE, CONCAT, and maybe one or two others.
However, if the data / input has even a moderate level of complexity, then the built-in T-SQL functions will be at best be cumbersome, and at worst useless. In such cases it's possible to do actual RegEx via SQLCLR (as long as you aren't using Azure SQL Database Single DB or SQL Server 2017+ via AWS RDS), which is (restricted) .NET code running within SQL Server. You can either code your own / find examples here on S.O. or elsewhere, or try a pre-done library such as the one I created, SQL# (SQLsharp), the Free version of which contains several RegEx functions. Please note that SQLCLR, being .NET, is not a POSIX-based RegEx, and hence does not use POSIX character classes (meaning: you will need to use \d for "digits" instead of [:digit:]).
The level of complexity needed in this particular situation is unclear as the example code in the question implies that the data is simple and uniform (i.e. 1112223333) but the example data shown in a comment on the question appears to indicate that there might be dashes and/or spaces in the data (i.e. xxx- xxx xxxx).
If the data truly is uniform, then stick with the pure T-SQL solution provided by #MartinSmith. But, if the data is of sufficient complexity, then please consider the RegEx example below, using a SQLCLR function found in the Free version of my SQL# library (as mentioned earlier), that easily handles the 3 variations of input data and more:
SELECT SQL#.RegEx_Replace4k(tmp.phone,
N'\(?(\d{3})\)?[ .-]*(\d{3})[ .-]*(\d{4})', N'($1)$2-$3',
-1, -- count (-1 == unlimited)
1, -- start at
N'') -- RegEx options
FROM (VALUES (N'8885551212'),
(N'123- 456 7890'),
(N'(777) 555- 4653')
) tmp([phone]);
returns:
(888)555-1212
(123)456-7890
(777)555-4653
The RegEx pattern allows for:
0 or 1 (
3 decimal digits
0 or 1 )
0 or more of , ., or -
3 decimal digits
0 or more of , ., or -
4 decimal digits
NOTE
It was mentioned that the newer Language Extensions might be a better choice than SQLCLR. Language Extensions allow calling R / Python / Java code, hosted outside of SQL Server, via the sp_execute_external_script stored procedure. As the Tutorial: Search for a string using regular expressions (regex) in Java page shows, external scripts are actually not a good choice for many / most uses of RegEx in SQL Server. The main problems are:
Unlike with SQLCLR, the only interface for external scripts is a stored procedure. This means that you can't use any of that functionality inline in a query (SELECT, WHERE, etc).
With external scripts, you pass in the query, work on the results in the external language, and pass back a static result set. This means that compiled code now has to be more specialized (i.e. tightly-coupled) to the particular usage. Changing how the query uses RegEx and/or what columns are returned now requires editing, compiling, testing, and deploying the R / Python / Java code in addition to (and coordinated with!) the T-SQL changes.
I'm sure external scripts are absolutely wonderful, and a better choice than SQLCLR, in certain scenarios. But they certainly do not lend themselves well to the highly varied, and often ad hoc, nature of how RegEx is used (like many / most other functions).
SQL Server does not have native regex support. You would need to use CLR (or as #Lukasz Szozda points out in the comments one of the newer Language Extensions) .
If I have understood the regex correctly though it matches strings of 10 digits and assigns the first 3 to group 1, second 3 to group 2, and last 4 to group 3 and then uses the back references in the expression (\1)\2-\3
You can use built in string functions to do this as below
SELECT CASE
WHEN phonenumber LIKE REPLICATE('[0-9]', 10)
THEN FORMATMESSAGE('(%s)%s-%s',
LEFT(phonenumber, 3),
SUBSTRING(phonenumber, 4, 3),
RIGHT(phonenumber, 4))
ELSE phonenumber
END
You can write SQL function using CLR, that will wrap standard dotnet regex. I have wrote this and you can use it there. It will look this:
DECLARE #SourceText NVARCHAR(MAX) = N'My first line <br /> My second line';
DECLARE #RegexPattern NVARCHAR(MAX) = N'([<]br\s*/[>])';
DECLARE #Replacement NVARCHAR(MAX) = N''
DECLARE #IsCaseSensitive BIT = 0;
SELECT regex.Replace(#SourceText, #RegexPattern, #Replacement, #IsCaseSensitive);

Replace is not working for weird character

I use UPDATE a SET GR_P = REPLACE(GR_P,'','') FROM mytable a to replace things.
But replace function is not working for below charter:
In Query analyzer it works but when I used SSIS Execute SQL task or OLEDB Source then it is giving me error:
No Connection manager is specified.
In Toad against Oracle (since that's one of your tags), I issued this (pressing ALT-12 to get the female symbol) and got 191 as a result. note selecting it back using CHR(191) shows an upside-down question mark though.
select ascii('♀') from dual;
Given that, this worked but it's Oracle syntax, your mileage may vary.
UPDATE mytable SET GR_P = REPLACE(GR_P, CHR(191));
Note if it does not work, that symbol could be for another control character. You may need to use a regular expression to eliminate all characters not in a-zA-Z0-9, etc. I suspect you'll need to update your tags to get a more accurate answer.
Maybe this info will help anyway. Please post back what you find out.

Setting the identifier quote character in Linq2Db

I find it hard to imagine that this question hasn't been asked before, but I couldn't find it.
I would like to use Linq2Db for Sybase and I need to change the identifier quoting characters from [ and ] to " and ", which is what Sybase uses. Is there anyway to do this? I tried looking at the linq2db source code once and it appears that these characters are hard coded, but I'm not sure (I think it would be silly to hard code them). Using Linq2db as it comes always produces errors around the "[" when Sybase executes the queries.
This is Sybase ASE 12.5, and it does not like [];
Here are some sample queries and the error message:
set quoted_identifier on
select * from "client" where clnt_id=140
select * from [client] where clnt_id=140
the first query works, but the second gives:
Incorrect syntax near '['. [SQLCODE=102, SQLSTATE="42000", Server=testtrng_ss1, Severity Level=15, State=1, Transaction State=1, Line=3]

Why SQL Server doesn't treat this code erratic? [duplicate]

Shouldn't one of these statements work and one fail?
Intuition says Statement 2 should fail because there is a comma after int and no second column listed.
Yet both work and the trailing comma "," after the last column data type makes no difference.
-- Statement 1
CREATE TABLE dbo.MyTable1( col1 int);
-- Statement 2
CREATE TABLE dbo.MyTable2( col1 int,);
However (and this is expected): two commas ",," after the last field do cause a failure:
-- Statement 3
CREATE TABLE dbo.MyTable3( col1 int,,);
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
Testing shows that its not just any character after the last field that is allowed through. For example, this fails:
-- Statement 3
CREATE TABLE dbo.MyTable3( col1 int ~);
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '~'.
Maybe SQL Server is "saving a seat at the table" for something? The Primary Key perhaps? I really don't know.
I am using Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64).
See http://connect.microsoft.com/SQLServer/feedback/details/273348/trailing-comma-allowed-in-create-table:
Description
When executing the CREATE TABLE command, a trailing comma following
the last column is allowed. Based on the grammar in BOL and comma
usage in lists in other T-SQL statements, this behavior is
inconsistent. This is a very minor issue and does not appear to cause
any adverse side-effects. It just appears that the parser may be a bit
off.
Microsoft views this as a bug, but a minor one.
This was resolved some time ago as "won't fix" but we didn't explain why. Simply, this seems pretty harmless, and not worth fixing in a service pack. We may consider fixing this in a future release.
It should be flagged as a syntax error, but there is a bug in SQL Server that doesn't treat the trailing comma as a syntax error.
Source: Microsoft Support (The affected versions in the list - 6, 6.5, and 2000 - are old, but I guess it's still around because it just worked for me in 2008.)
Almost all languages which permit comma-separated list items permit a comma after the last list item. This is done to make editing the program or file, and especially inserting new list items, easier. You don't have to worry about adding a comma after the current last list item, or removing a comma if you delete the old last list item.

Resources