How to use special characters in SQL Server variables? - sql-server

I'm trying to declare a variable like #wi-fi in SQL Server but dash character in not allowed. There are other characters like / * - ( ) with same problem. I know for table or column name we can put it in the [] but what about declaring variables? is there a solution?
I have already searched the web but couldn't find any way.

Local variable names must comply with the rules for identifiers. MSDN says that :
When identifiers are used in Transact-SQL statements, the identifiers that do not comply with these rules must be delimited by double quotation marks or brackets.
But this rule is not valid for variables naming. In SQL Server there is a restriction on variable names. All variable names must begin with a single # sign. After that the variable name must follow the rules for identifiers and can contain a total of 128 characters.When we say characters, we mean that the name can contain letters, numbers, the # sign, the pound sign, the dollar sign and the underscore character. The variable name can not contain any dash or spaces.
READ MORE HERE

Some context to answer people such as #Alex who need to know the "why" for questions like this:
I ran into a similar problem, I needed to use just a small piece of a URL saved in my db where the front and ends were irrelevant.
I first attempted to use:
declare #variable varchar(250) = %x%;
SELECT * FROM tblone WHERE column1 LIKE '#variable'
however this returned error: Arithmetic overflow error converting numeric to data type varchar
My working query was formatted:
declare #variable varchar(1000) = x;
SELECT * FROM tblone WHERE column1 LIKE '%'+#variable+'%'

Related

SQL Server string comparison with equals sign and equals or greater in the strings [duplicate]

I have seen prefix N in some insert T-SQL queries. Many people have used N before inserting the value in a table.
I searched, but I was not able to understand what is the purpose of including the N before inserting any strings into the table.
INSERT INTO Personnel.Employees
VALUES(N'29730', N'Philippe', N'Horsford', 20.05, 1),
What purpose does this 'N' prefix serve, and when should it be used?
It's declaring the string as nvarchar data type, rather than varchar
You may have seen Transact-SQL code that passes strings around using
an N prefix. This denotes that the subsequent string is in Unicode
(the N actually stands for National language character set). Which
means that you are passing an NCHAR, NVARCHAR or NTEXT value, as
opposed to CHAR, VARCHAR or TEXT.
To quote from Microsoft:
Prefix Unicode character string constants with the letter N. Without
the N prefix, the string is converted to the default code page of the
database. This default code page may not recognize certain characters.
If you want to know the difference between these two data types, see this SO post:
What is the difference between varchar and nvarchar?
Let me tell you an annoying thing that happened with the N' prefix - I wasn't able to fix it for two days.
My database collation is SQL_Latin1_General_CP1_CI_AS.
It has a table with a column called MyCol1. It is an Nvarchar
This query fails to match Exact Value That Exists.
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = 'ESKİ'
// 0 result
using prefix N'' fixes it
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = N'ESKİ'
// 1 result - found!!!!
Why? Because latin1_general doesn't have big dotted İ that's why it fails I suppose.
1. Performance:
Assume your where clause is like this:
WHERE NAME='JON'
If the NAME column is of any type other than nvarchar or nchar, then you should not specify the N prefix. However, if the NAME column is of type nvarchar or nchar, then if you do not specify the N prefix, then 'JON' is treated as non-unicode. This means the data type of NAME column and string 'JON' are different and so SQL Server implicitly converts one operand’s type to the other. If the SQL Server converts the literal’s type
to the column’s type then there is no issue, but if it does the other way then performance will get hurt because the column's index (if available) wont be used.
2. Character set:
If the column is of type nvarchar or nchar, then always use the prefix N while specifying the character string in the WHERE criteria/UPDATE/INSERT clause. If you do not do this and one of the characters in your string is unicode (like international characters - example - ā) then it will fail or suffer data corruption.
Assuming the value is nvarchar type for that only we are using N''

unable to update nvarchar(50) having czech letters in it [duplicate]

I have seen prefix N in some insert T-SQL queries. Many people have used N before inserting the value in a table.
I searched, but I was not able to understand what is the purpose of including the N before inserting any strings into the table.
INSERT INTO Personnel.Employees
VALUES(N'29730', N'Philippe', N'Horsford', 20.05, 1),
What purpose does this 'N' prefix serve, and when should it be used?
It's declaring the string as nvarchar data type, rather than varchar
You may have seen Transact-SQL code that passes strings around using
an N prefix. This denotes that the subsequent string is in Unicode
(the N actually stands for National language character set). Which
means that you are passing an NCHAR, NVARCHAR or NTEXT value, as
opposed to CHAR, VARCHAR or TEXT.
To quote from Microsoft:
Prefix Unicode character string constants with the letter N. Without
the N prefix, the string is converted to the default code page of the
database. This default code page may not recognize certain characters.
If you want to know the difference between these two data types, see this SO post:
What is the difference between varchar and nvarchar?
Let me tell you an annoying thing that happened with the N' prefix - I wasn't able to fix it for two days.
My database collation is SQL_Latin1_General_CP1_CI_AS.
It has a table with a column called MyCol1. It is an Nvarchar
This query fails to match Exact Value That Exists.
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = 'ESKİ'
// 0 result
using prefix N'' fixes it
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = N'ESKİ'
// 1 result - found!!!!
Why? Because latin1_general doesn't have big dotted İ that's why it fails I suppose.
1. Performance:
Assume your where clause is like this:
WHERE NAME='JON'
If the NAME column is of any type other than nvarchar or nchar, then you should not specify the N prefix. However, if the NAME column is of type nvarchar or nchar, then if you do not specify the N prefix, then 'JON' is treated as non-unicode. This means the data type of NAME column and string 'JON' are different and so SQL Server implicitly converts one operand’s type to the other. If the SQL Server converts the literal’s type
to the column’s type then there is no issue, but if it does the other way then performance will get hurt because the column's index (if available) wont be used.
2. Character set:
If the column is of type nvarchar or nchar, then always use the prefix N while specifying the character string in the WHERE criteria/UPDATE/INSERT clause. If you do not do this and one of the characters in your string is unicode (like international characters - example - ā) then it will fail or suffer data corruption.
Assuming the value is nvarchar type for that only we are using N''

When/ why would you use QUOTENAME in SQL?

I understand that the QUOTENAME function can be used to add square brackets ([], the default behaviour) or some other character wrapper to strings. It doesn't work for longer strings (over 128 characters).
So... Why/ when would you use it instead of the more conventional and far more easily readable string concatenation?
Why would you not just concatenate a single quote or a square bracket at the beginning and end of a term and use this function instead?
It is/was specifically designed for quoting column/table/database names – sysnames. For example, this: SELECT QUOTENAME('abc[]def') returns [abc[]]def] while SELECT '[' + 'abc[]def' + ']' returns [abc[]def] which is invalid to use as a column/table/database name.
Additionally, the SQL-99 standard is to quote by using a single quote character, and while current versions of Sql Server continue to use brackets, it may in the future (or be configurable to be) use the SQL-99 standard. In which case, all code using QUOTENAME will continue to function correctly, while code that tries to do its own escaping will fail.
There is more subtle implications as well. Since QUOTENAME has the exact same limitations as sysname, should Microsoft ever decide to change sysname to be longer than 128 characters (256 maybe? 32767 maybe?), it would be assumed that QUOTENAME would then also be able to handle these increased sizes. Using QUOTENAME is a safe(r) way of taking a column name from a possibly untrusted source and using it as a sysname – no matter the current/future database settings without having to worry about the edge cases (like ] or ' inside the input) and whether it will allow the string to break out of the column name to create SQL injection attacks. I probably wouldn't depend solely on this feature for security, but to be used in one of many layers of protection.
You use QUOTENAME() mainly when you need to build dynamic sql. Dynamic SQL is something you should avoid as much as possible, but in rare situations it can be the best way to solve a problem. When building dynamic SQL, QUOTENAME() is the correct way to ensure table and column name variables that may include unwanted characters like spaces won't cause problems with your final SQL statement.
QuoteName is primarily designed for SYSNAME like datatypes. This sysname datatype is unicode of 128 characters which is NVARCHAR(128). Hence if it is more than 128 characters you need to use traditional way of concatenating. But we can use QUOTENAME for varchar, nvarchar and sysname datatypes..
declare #test NVARCHAR(1000) = replicate('a',500)
declare #testsysname sysname = replicate('a',500)
select QUOTENAME(#test) -- this returns null
select QUOTENAME(#testsysname) --this displays only for 128 character with brackets

T-SQL Regex for social security number (SQL Server 2008 R2)

I need to find invalid social security numbers in a varchar field in a SQL Server 2008 database table. (Valid SSNs are being defined by being in the format ###-##-#### - doesn't matter what the numbers are, as long as they are in that "3-digit dash 2-digit dash 4-digit" pattern.
I do have a working regex:
SELECT *
FROM mytable
WHERE ssn NOT LIKE '[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]'
That does find the invalid SSNs in the column, but I know (okay - I'm pretty sure) that there is a way to shorten that to indicate that the previous pattern can have x iterations.
I thought this would work:
'[0-9]{3}-[0-9]{2}-[0-9]{4}'
But it doesn't.
Is there a shorter regex than the one above in the select, or not? Or perhaps there is, but T-SQL/SQL Server 2008 doesn't support it!?
If you plan to get a shorter variant of your LIKE expression, then the answer is no.
In T-SQL, you can only use the following wildcards in the pattern:
%
- Any string of zero or more characters.
WHERE title LIKE '%computer%' finds all book titles with the word computer anywhere in the book title.
_ (underscore)
Any single character.
WHERE au_fname LIKE '_ean' finds all four-letter first names that end with ean (Dean, Sean, and so on).
[ ]
Any single character within the specified range ([a-f]) or set ([abcdef]).
WHERE au_lname LIKE '[C-P]arsen' finds author last names ending with arsen and starting with any single character between C and P, for example Carsen, Larsen, Karsen, and so on. In range searches, the characters included in the range may vary depending on the sorting rules of the collation.
[^]
Any single character not within the specified range ([^a-f]) or set ([^abcdef]).
So, your LIKE statement is already the shortest possible expression. No limiting quantifiers can be used (those like {min,max}), not shorthand classes like \d.
If you were using MySQL, you could use a richer set of regex utilities, but it is not the case.
I suggest you to use another solution like this:
-- Use `REPLICATE` if you really want to use a number to repeat
Declare #rgx nvarchar(max) = REPLICATE('#', 3) + '-' +
REPLICATE('#', 2) + '-' +
REPLICATE('#', 4);
-- or use your simple format string
Declare #rgx nvarchar(max) = '###-##-####';
-- then use this to get your final `LIKE` string.
Set #rgx = REPLACE(#rgx, '#', '[0-9]');
And you can also use something like '_' for characters then replace it with [A-Z] and so on.

Do I have use the prefix N in the "insert into" statement for unicode?

Like:
insert into table (col) values (N'multilingual unicode strings')
I'm using SQL Server 2008 and I already use nVarChar as the column data type.
You need the N'' syntax only if the string contains characters which are not inside the default code page. "Best practice" is to have N'' whenever you insert into an nvarchar or ntext column.
Yes, you do if you have unicode characters in the strings.
From books online (http://msdn.microsoft.com/en-us/library/ms191313.aspx)...
"Unicode string constants that appear in code executed on the server, such as in stored procedures and triggers, must be preceded by the capital letter N. This is true even if the column being referenced is already defined as Unicode. Without the N prefix, the string is converted to the default code page of the database. This may not recognize certain characters. The requirement to use the N prefix applies to both string constants that originate on the server and those sent from the client."
It is preferable for compatibility sake.
Best practice is to use parameterisation in which case you don't need the N prefix.

Resources