script issue Transact-SQL - sql

I Want to return All table names from a use data base but this just return a char
declare #contador int
set #contador = 1
while (#contador<=(select count(table_name) from INFORMATION_SCHEMA.TABLES))
begin
declare #tableName varchar
set #tableName = (select top 1 * from (select top(#contador) table_name from INFORMATION_SCHEMA.TABLES order by table_name asc) as nombre order by table_name desc)
print #tableName
set #contador = #contador + 1
end
the output is s
s
s
s
s
s

declare #tableName varchar(100)
You need to define the length of #tableName, by default it is set to 1 character.

try
declare #tableName varchar(100)

You need to change your tablename to have a value for the number of characters. Currently that value is defaulted to one. I would suggest a much larger value than you think you neeed to ensure that all tables fit inside the field.

declare #tableName varchar needs to have a size like varchar(50)

T-SQL has the type SYSNAME for storing things like table names:
The sysname data type is used for table columns, variables, and stored
procedure parameters that store object names. The exact definition of
sysname is related to the rules for identifiers. Therefore, it can
vary between instances of SQL Server. sysname is functionally the same
as nvarchar(128) except that, by default, sysname is NOT NULL. In
earlier versions of SQL Server, sysname is defined as varchar(30).
So try declaring your variable like this:
DECLARE #tableName SYSNAME;
Using the VARCHAR(100) declaration, as suggested in other answers, will fail if the table name contains characters outside your current code page or is longer than 100 characters.
This excerpt from SQL Server's rules for identifiers describes the form of a table name:
The first character must be one of the following:
A letter as defined by the Unicode Standard 3.2. The Unicode
definition of letters includes Latin characters from a through z, from
A through Z, and also letter characters from other languages.
The underscore (_), at sign (#), or number sign (#).
Certain symbols at the beginning of an identifier have special meaning
in SQL Server. A regular identifier that starts with the at sign
always denotes a local variable or parameter and cannot be used as the
name of any other type of object. An identifier that starts with a
number sign denotes a temporary table or procedure. An identifier that
starts with double number signs (##) denotes a global temporary
object. Although the number sign or double number sign characters can
be used to begin the names of other types of objects, we do not
recommend this practice.
Some Transact-SQL functions have names that start with double at signs
(##). To avoid confusion with these functions, you should not use
names that start with ##.
Subsequent characters can include the following:
Letters as defined in the Unicode Standard 3.2.
Decimal numbers from either Basic Latin or other national scripts.
The at sign, dollar sign ($), number sign, or underscore.
The identifier must not be a Transact-SQL reserved word. SQL Server
reserves both the uppercase and lowercase versions of reserved words.
Embedded spaces or special characters are not allowed.
Supplementary characters are not allowed.
See the documentation links in my answer for more information.

Related

LIKE operator, N and % SQL Server doesn't work on nvarchar column

Is there any way to make following query Work?
declare #t nvarchar(20)
set #t='حس'
SELECT [perno] ,[pName]
FROM [dbo].[People]
Where [pName] like N''+#t +'%'
I cann't use like this:
Where [pName] like N'حس%'
Or using an stored procedure :
ALTER PROCEDURE [dbo].[aTest]
(#t nvarchar(20))
AS
BEGIN
SELECT [perno] ,[pName]
FROM [dbo].[People]
WHERE ([People].[pName] LIKE N'' +#t + '%')
END
You don't need to use N prefix in the WHERE clause since your variable is already nvarchar, and you are passing a variable not a literal string.
Here is an example:
CREATE TABLE People
(
ID INT,
Name NVARCHAR(45)
);
INSERT INTO People VALUES
(1, N'حسام'),
(2, N'حسان'),
(3, N'حليم');
DECLARE #Name NVARCHAR(45) = N'حس';--You need to use N prefix when you pass the string literal
SELECT *
FROM People
WHERE Name LIKE #Name + '%'; --You can use it here when you pass string literal, but since you are passing a variable, you don't need N here
Live demo
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.
From docs
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.
To answer your question in the comment with a simple answer, you are using the wrong datatype, so ALTER the stored procedure and change the datatype of your parameter from VARCHAR to NVARCHAR.
UPDATE:
Since you are using an SP, you can create your SP (according to your comment) as
CREATE PROCEDURE MyProc
(
#Var NVARCHAR(45)
)
AS
BEGIN
SELECT *
FROM People
WHERE Name LIKE ISNULL(#Var, Name) + '%';
--Using ISNULL() will return all rows if you pass NULL to the stored procedure
END
and call it as
EXEC MyProc N'حس'; --If you don't use N prefix then you are pass a varchar string
If you see, you need to use the N prefix when you pass literal string to your SP not inside the SP or the WHERE clause neither.
Demo for the SP
in these lines
declare #t nvarchar(20)
set #t='حس'
the 'حس' is a varchar constant that you then assign to an nvarchar variable. But you already lost data with the original conversion to that varchar constant and you cannot get that back.
The solution is to use an nvarchar constant:
set #t=N'حس'
It might be much simpler:
Try this
declare #t nvarchar(20)
set #t='حس';
SELECT #t; --the result is "??"
You are declaring the variable as NVARCHAR correctly. But the literal does not know its target. Without the N it is taken as a VARCHAR with the default collation.
The following line
Where [pName] like N''+#t +'%'
will search for a pName LIKE '??%'.
The solution should be
set #t=N'حس'; --<-- N-prefix

Create INSERT statement using parameter

I need to create a INSERT statement using parameters. Say I have two variable name #DestinationFields, #InsertValues.
Here #DestinationFields contain the column name like: product,price and #InsertValues contains the values for those two columns, like: Book,100.
Now, How i create a insert command to insert those values where each value need to add a quotation mark .I already tried as
I already tried as
EXEC('INSERT into tbl_test('+#DestinationFields+')values('+#InsertValues+')')
But it's returning an error.
The name "book" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some
contexts) variables. Column names are not permitted.
How do I do it? Thanks in advance.
Pretending there is no problem of SQL injection here*, you can quickly fix your code by adding quotation marks around Book. The value of # InsertValues should be
'Book', 100
instead of simply
Book, 100
You need to add quotation marks around each string value; otherwise, strings are interpreted as names, which is not valid.
EDIT : (in response to a comment) If all columns are of varchar type, you can put quotes around the entire string, and replace all commas with the quote-comma-quote pattern, like this:
values('''+REPLACE(#InsertValues,',',''',''')+''')'
* You should not put code like this into production, because it can be manipulated to harm your system rather severely. Here is a good illustration of the problem (link).
Try:
DECLARE #DestinationFields VARCHAR(200);
SET #DestinationFields = 'Col1, Col2, Col3'
DECLARE #InsertValues VARCHAR(200);
SET #InsertValues = '1, 2, 3'
DECLARE #SQLString VARCHAR(1000);
SET #SQLString = 'INSERT INTO tbl_test (' + #DestinationFields + ') VALUES (' + #InsertValues + ')';
EXEC (#SQLString)
However, this is very open to SQL Injection attacks. But, it will do what you require.
The Curse and Blessing of Dynamic SQL

SQL Server query: what is the meaning of 'N' preceding a string?

In SQL Server, the query
SELECT custid, country, region, city
FROM Sales.Customers
WHERE region = N'WA'
what is the meaning of 'N' in the where clause? I remove it, get same result.
It is casting your literal to a Unicode string.
See here for official explanation:
Unicode strings have a format similar to character strings but are preceded by an N identifier (N stands for National Language in the SQL-92 standard).
In many cases, it won't make a difference, unless your literal contains Unicode characters. If it does, and you leave out the explicit cast, it will convert your Unicode characters to a '?':
select 'Ộ', N'Ộ'
---- ----
? Ộ
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.
For example, the stored procedure created in the previous example can be executed on the server in the following way:
EXECUTE Product_Info #name = N'Chain'
The requirement to use the N prefix applies to both string constants that originate on the server and those sent from the client.
'N' stands for National Language and denotes that you are passing a value for NVARCHAR, NCHAR. The data types that accept languages other than English start with N.
Keep in mind that you are not required to wrap your parameter with 'N' for data types like VARCHAR, CHAR because they don't accept Unicode characters.
Any other language such as Arabic, Farsi will be considered as Unicode so they should be manipulated in data types like NVARCHAR and values should be wrapped with 'N' as below:
DECLARE #Name AS NVARCHAR(50);
SET #Name = N'اسم';
PRINT #Name;
This will return:
اسم
If you try without 'N':
DECLARE #Name AS NVARCHAR(50);
SET #Name = 'اسم';
PRINT #Name;
This will return
???
It is because you haven't wrapped the value with 'N' although the data type is NVARCHAR and system doesn't know anything about the word 'اسم'.

Convert Binary Id Field to Text

I need the text (representation) of a id field in SQL Server 2005. Is there a way, we can generate the textual representation of the id field?
For instance, if the id field reads as 0x00000000000002F0, I need the text value of 0x00000000000002F0 so that I can run SUBSTR operations on the same.
Constraints
I am not allowed to create a stored procedure in the Database (as creation of SP is not allowed)
Thanks!
You can convert unicode strings to binary using
SELECT CONVERT(VARBINARY(40),N'Hello World')
(returns 0x480065006C006C006F00200057006F0072006C006400)
Convert from binary back to unicode using
SELECT CONVERT(NVARCHAR(20), 0x480065006C006C006F00200057006F0072006C006400)
(returns 'Hello World')
Whilst it's not immediately obvious to me why you would want to do this for comparison purposes (as opposed to matching binary values), the undocumented function sys.fn_varbintohexstr should do the trick
declare #vb binary(8)
,#vc varchar(20)
set #vb = 0x00000000000002F0
set #vc = sys.fn_varbintohexstr(#vb)
--prove that this works by concatenating a string to the varchar value
select #vb, '#' + #vc

T-sql COLLATE and Varchar(max)

When u use Varchar(max), it is 8000 chars for a variable, and around 2^32 for a column, what is COLLATE and how it affects that?
Thanks
Collation deterines how SQL Server sorts and compares string data (which varchar variables and column values are).
See here
When you declare a column or a variable of varchar(max), it can take up to 2 GB of data and 2^31-1 characters. If you declare the column or variable as nvarchar, it can still only take 2 GB of data and (2^31-1) / 2 characters since each character takes up twice as much space. When you declare a varchar column or variable without the use of the COLLATE clause, the collation of the database is used. The ``COLLATE clause does not affect the capacity of the column or variable.