Size limit for nvarchar(max) , Print issue - sql

I want to save XML record that length is more than 43679 char and its saved into table.
Because when i'm checking its length its giving more than 43679 char but when i'm going to read or Print data of this column its only showing 43679 char.
The below image can help you to understand the problem.
like example
declare #t table (a nvarchar(max));
insert into #t (a) values (REPLICATE(CONVERT(nvarchar(max),'a'),200000));
select LEN(a) from #t -- result 200000
select print(a) from #t -- print only 43679 char.
Please help me out of this situation.

This is a well known bug in SSMS, You can't paste more than 43679 char from a grid view column and unfortunately this limit can't be increased, You can get around this by displaying your Data in Xml format instead of nvarchar

The datatypes like NCHAR, NVARCHAR, NVARCHAR(MAX) stores half of CHAR, VARCHAR & NVARCHAR(MAX). Because these datatype used to store UNICODE characters. Use these datatypes when you need to store data other then default language (Collation). UNICODE characters take 2 bytes for each character. That's why lenth of NCHAR, NVARCHAR, NVARCHAR(MAX) stores half of CHAR, VARCHAR & NVARCHAR(MAX).

SQL Server Management Studio has a character limit when printing to the messages pane. There is a workaround to achieve what you need.
Using FOR XML to select your data using TYPE you can specify [processing-instruction] and give it a name. Your text will be presented as a link which you can open. This text will have wrappers and the name you specified. Here is an example.
declare #t table (a nvarchar(max));
insert into #t (a) values (REPLICATE(CONVERT(nvarchar(max),'a'),200000));
select LEN(a) from #t -- result 200000
SELECT a [processing-instruction(TextOutput)] from #t FOR XML PATH(''), TYPE;

Related

[Insert Destination [26]] Error: Column "GovtProgYN" cannot convert between unicode and non-unicode string data types

I am executing an ETL process and getting captioned error:
source datatype is char(1) and destination datatype is nchar(2)
How do I insert data from char to nchar?
Please help.
You don't say what platform you are using but you need to tell it to convert. Something like
SELECT CAST(GOVTPROGYN as NCHAR(2)) FROM TABLENAME_YOU_DID_NOT_SAY
or
SELECT CAST(GOVTPROGYN as CHAR(1)) FROM TABLENAME_YOU_DID_NOT_SAY
Per your title error, the n in nchar adds support for unicode, (same with nvarchar vs varchar). The data you are trying to insert is type char, but your destination field (GovtProgYN?) requires nchar.
Most SQL engines support a CAST function, which looks something like this: CAST( field AS datatype ). In your case, you would want to cast your insert value to nchar(2).
Example:
INSERT INTO Table ( GovtProgYN )
VALUES ( CAST ( #value AS nchar(2) )
Some SQL engines, like SQL Server, require you to designate unicode using the N prefix to a character string. If you are trying to manually insert a nchar value, use N'c' rather than 'c'.
Example:
INSERT INTO Table ( GovtProgYN )
VALUES ( N'c' )

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

SSIS / SQL Server - dealing with various money type notations

In a SQL Server money column how can I deal with different currency notations coming in from country specific Excel files via SSIS (in varchar - transformed to money), taking care of comma and dot representation to make sure the values stay correct?
For example if these are three column values in Excel:
22,333.44
22.333,44
22333,44
the first notation above will result in 22,3334, which of course is incorrect.
What do I need to do with the data? Is it a string replace or something more elegant?
thank you.
UPDATED:
After discussion in comments the problem has been clarified. The values in the excel column can be of many different regional formats (English using commas to separate thousands and '.' for decimal point, German using '.' for separating thousands and comma for decimal point).
Assuming that the destination format is English and you don't have an accompanying column to indicate the format then you're gonna have to implement a kludge of a workaround. If you can guarantee there will always be 2 numbers after the "decimal place" (comma in german format) then REPLACE(REPLACE(#Value,',',''),'.','') will get rid of every comma/point. Then you will have to get the length of the resulting varchar and manually insert a decimal (or comma) before the last 2 characters. Here's a sample implementation:
declare #number varchar(12),#trimmednumber varchar(12),#inserteddecimal varchar(12)
set #number='22.333,44'
select #trimmednumber=REPLACE(REPLACE(#number,',',''),'.','')
select #inserteddecimal=(LEFT(#trimmednumber,len(#trimmednumber)-2) + '.' + RIGHT(#trimmednumber,2))
select #number AS [Original],#trimmednumber AS [Trimmed],#inserteddecimal AS [Result]
And the results:
Original Trimmed Result
------------ ------------ ------------
22.333,44 2233344 22333.44
Original Answer:
I may be misunderstanding your question but if you take in those values as VARCHAR and insert them into MONEY columns then the implicit conversion should be correct.
Here's what I've knocked together to test:
declare #money_varchar1 varchar(12),#money_varchar2 varchar(12),#money_varchar3 varchar(12)
set #money_varchar1='22,333.44'
set #money_varchar2='22.333,44'
set #money_varchar3='22333,22'
declare #table table (Value money)
insert into #table values (#money_varchar1)
insert into #table values (#money_varchar2)
insert into #table values (#money_varchar3)
select * from #table
And the results:
Value
---------------------
22333.44
22.3334
2233322.00

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