T-sql COLLATE and Varchar(max) - sql

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.

Related

How can varchar containing integer work in calculations

How come string can contain integer. Even if I assume string storing numeric values as string, but even i can use in it calculation and getting the result as well. Just to try I wrote 5 in inverted commas and still calculation works fine. Not sure how?
declare #x varchar(20)
declare #y int
select #x='5'
select #y=6
select #x+#y
SQL Server -- and all other databases -- convert values among types when the need arises.
In this case, you have + which can be either string concatenation or number addition. Because one argument is an integer, it is interpreted as addition, and SQL Server attempts to convert the string to a number.
If the string cannot be converted, then you will get an error.
I would advise you to do your best to avoid such implicit conversions. Use the correct type when defining values. If you need to store other types in a string, use cast()/convert() . . . or better yet, try_cast()/try_convert():
try_convert(int, #x) + #y
A varchar can contain any character from the collations codepage you are using. For the purposes of this answer, I'm going to assume you're using something like the collation SQL_Latin1_General_CP1_CI_AS (which doesn't have any "international" characters, like Kanji, Hiragana, etc).
You first declare the variable #x as a varchar(20) and put the varchar value '5' in it. This is not an int, it's a varchar. This is an important distinction as a varchar and a numerical data type (like an int) behave very differently. For example '10' has a lower value than '2', where as the opposite is true for 10 and 2. (This is one reason why using the correct data type is always important.)
Then the second variable you have is #y, which is an int and has the value 6.
Then you have your expression SELECT #x+#y;. This has 2 parts to it. Firstly, as you have 2 datatypes, Data Type Precedence comes into play. int has a higher precedence than a varchar, and so #x is implicitly converted to an int. Then the expression is calculated, uses + as an addition operator (not a concatenation operator). Therefore the expression is effectively derived like this:
#x + #y = '5' + 6 = CONVERT(int,'5') + 6 = 5 + 6 = 11
SQL Server uses the following precedence order for data types:
user-defined data types (highest)
sql_variant
xml
datetimeoffset
datetime2
datetime
smalldatetime
date
time
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
image
timestamp
uniqueidentifier
nvarchar (including nvarchar(max) )
nchar
varchar (including varchar(max) )
char
varbinary (including varbinary(max) )
binary (lowest)

Nvarchar working with logical operator working?

Just need your help here.
I have a table T
A (nvarchar) B()
--------------------------
'abcd'
'xyzxcz'
B should output length of entries in A for which I did
UPDATE T
SET B = LEN(A) -- I know LEN function returns int
But when I checked out the datatype of B using sp_help T, it showed column B as nvarchar.
What's going on ?
select A
from T
where B > 100
also returned correct output?
Why is nvarchar working with logical operators ?
Please help.
Check https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine?view=sql-server-2017 where it is said that data types are converted explicitly or implicitly when you move, compare or store a variable. In your case, you are comparing column B with 100, forcing sql server to implicitly convert it to integer type (check the picture about conversions on the same page). As a prove, try to alter a row putting some text in column B and, after repeating your select query B>100, sql server will throw a conversione error trying to obtain an integer out of your text.
It works because of implicit conversion between types.
Data type precedence
When an operator combines expressions of different data types, the data type with the lower precedence is first converted to the data type with the higher precedence. If the conversion isn't a supported implicit conversion, an error is returned.
Types precedence:
16. int
...
25. nvarchar (including nvarchar(max) )
In you example:
select A
from T
where B > 100
--nvarchar and int (B is implicitly casted to INT)
when adding a column to a table in ssms, not adding a datatype a "default" datatype is chosen. for me on 2017 developer it's nchar(10). if you want it to be int define the column with datatype of int. in tsql it'd be
create table T (
A nvarchar --for me the nvarchar without a size gives an nvarchar(2)
,B int
);
sp_help T
--to make a specific size, largest for nvarchar is 4000 or max...max is the replacement for ntext of old, as.
create table Tmax (
A nvarchar(max)
,B int
);
--understanding nvarchar and varchar for len() and datalength()
select
datalength(N'wibble') datalength_nvarchar -- nvarchar is unicode and uses 2 bytes per char, so 12
,datalength('wibble') datalength_varchar -- varchar uses 1 byte per so 6
,len(N'wibble') len_nvarchar -- count of chars, so 6
,len('wibble') len_varchar -- count of char so still 6
nvarchar(max) and varchar(max)
hope this helps, the question is a bit discombobulated

script issue Transact-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.

Column not updating when tried to update a value of type varchar

I am using SQL Server 2000. When I try to update a column of type varchar(20) with a text value of more than 10 characters, I get an error
String or binary data would be truncated.
Why is it? varchar(20) should accept a text of up to 20 characters... why can I not update it with text with more than 10 characters?
If your string variable is declared as nvarchar(n), then it will take up twice as much space as a varchar(n)
10 x 2 = 20
So, anything greater than 10 double-byte chars will not fit into a varchar(20)
If you are inserting/updating into a column of type varchar, also declare your string variable as varchar with the appropriate size.
declare #str varchar(20)

Unicode- VARCHAR and NVARCHAR

-- Creating Table
Create Table Test1
(
id Varchar(8000)
)
-- Inserting a record
Insert into Test1 Values ('我們的鋁製車架採用最新的合金材料所製成,不但外型輕巧、而且品質優良。為了達到強化效果,骨架另外經過焊接和高溫處理。創新的設計絕對能充分提升踏乘舒適感和單車性能。');
As I have defined data type of id as Varchar. The data is stored as ?????.
Do I have to use NVARCHAR..? What is Difference between VarChar and Nvarchar(). Please explain about UNIcode as well.
The column type nvarchar allows you to store Unicode characters, which basically means almost any character from almost any language (including modern languages and some obsolete languages), and a good number of symbols too.
also it is required to prefix N before your value. example Insert into Test1 Values (N'我們的鋁製車架採用最新的合金材料所製成,不但外型輕巧、而且品質優良。為了達到強化效果,骨架另外經過焊接和高溫處理。創新的設計絕對能充分提升踏乘舒適感和單車性能。'); or programatically use preparedstatement with bind values for inserting and updating natural characterset
Nvarchar supports UNICODE. SO yes. you need to have the column as nvarchar and not varchar.
Despite the collation of your database. Use nvarchar to store UNICODE.
Embbed your Unicode value in N'[value]'
INSERT INTO ... VALUES
('Azerbaijani (Cyrillic)', N'Aзәрбајҹан (кирил әлифбасы)', 'az-cyrl')
In DB: 59 Azerbaijani (Cyrillic) Aзәрбајҹан (кирил әлифбасы) az-cyrl
Important is the N prefix!
Valid for MS SQL 2014 I am using. Hope this helps.
Yes you have to use nvarchar or use a collation for the language set you want. But nvarchar is preferred. Goodgle can tell you what this stuff means.
Varchar uses Windows-1252 character encoding, which is for all practical purposes standard ASCII.
As others have noted, nvarchar allows the storage of unicode characters.
You can get the ASCII translations from either data type, as shown here:
IF OBJECT_ID('TEST1') IS NOT NULL
DROP TABLE TEST1
GO
CREATE TABLE TEST1(VARCHARTEST VARCHAR(8000), NVARCHARTEST NVARCHAR(4000))
-- Inserting a record
INSERT INTO TEST1 VALUES ('ABC','DEF')
SELECT
VARCHARTEST
,NVARCHARTEST
,ASCII(SUBSTRING(VARCHARTEST,1,1))
,ASCII(SUBSTRING(VARCHARTEST,2,1))
,ASCII(SUBSTRING(VARCHARTEST,3,1))
,ASCII(SUBSTRING(NVARCHARTEST,1,1))
,ASCII(SUBSTRING(NVARCHARTEST,2,1))
,ASCII(SUBSTRING(NVARCHARTEST,3,1))
FROM
TEST1
DROP TABLE TEST1