Ukrainian character change to question mark when insert to table - sql

I have a file saved as Unicode text containing Ukrainian characters, and it got loaded successfully to staging table using SSIS.
Like this:
"Колодки тормозные дисковые, комплект"
Колодки тормозные
"Колодки тормозные дисковые, комплект"
This is Test
But when I am moving it to other table it changes to:
"??????? ????????? ????????, ????????"
??????? ?????????
"??????? ????????? ????????, ????????"
This is Test
The query I used:
insert into finaltable
(
column1
)
select column1 from staging table.
Collation: Latin1_General_CI_AS
How can I rectify this error?

Here you can see the deference between VARCHAR and NVARCHAR datatypes:
DECLARE #Non_Unicode_Var VARCHAR (MAX) = 'Колодки тормозные дисковые, комплект';
DECLARE #Unicode_Var NVARCHAR (MAX) = N'Колодки тормозные дисковые, комплект';
SELECT #Non_Unicode_Var AS NonUnicodeColumn, #Unicode_Var AS UnicodeColumn;
Result:
+--------------------------------------+--------------------------------------+
| NonUnicodeColumn | UnicodeColumn |
+--------------------------------------+--------------------------------------+
| ??????? ????????? ????????, ???????? | Колодки тормозные дисковые, комплект |
+--------------------------------------+--------------------------------------+
So, you need to change the data type to NVARCHAR data type, then insert your data into the table.

Use nvarchar in your table and when you type your strings in the insert statement put N in front, like N'your string'. Also consider changing your collation due to sorting issues, refer to this question.

Related

Convert ntext to numeric

One of my column is defined as ntext datatype which is no longer supported by many streams. I'm trying my best to convert that column to numeric or int and every attempt is reaching anywhere.
reg_no #my ntext field | name | country | etc |
I tried to alter the col using the command we all use, but failed
alter table tabl1
alter column [reg_no] numeric(38,0)
Error:
Error converting data type nvarchar to numeric
Any suggestions on fixing this or has anyone come across this in the past, if yes how did you get over it
You should be able to do this in two steps:
alter table tabl1 alter column [reg_no] nvarchar(max);
alter table tabl1 alter column [reg_no] numeric(38,0);
ntext is deprecated and conversion to numeric is not supported, but converting to nvarchar() is supported.
This assumes that the values are compatible with numeric. Otherwise you will get a type conversion error. If this happens, you can get the offending values by using:
select *
from t
where try_convert(numeric(38, 0), try_convert(nvarchar(max), x)) is null
Try,
select convert(int,convcert(varchar(40), reg_no)) as newfieldname from tabl1

Using UPDATE statement with a SELECT statement converting hexadecimal to text

I have a table called Script_Data that has three columns - ScriptID (primary), RowOrder and ScriptData. each row value for ScripData is hexadecimal. For me to make sense of it, I convert it to text. I CAST() the ScriptData column into VarChar datatype using the following query
SELECT ScriptID, RowOrder, CAST(CAST(ScriptData AS varbinary(MAX)) AS varchar(MAX)) AS Converted_SD
FROM Script_Data
Is it possible to UPDATE values in the ScriptData column when converted? I know that I would typically do something like this if not for converting:
UPDATE Script_Data
SET ScriptData='Sales'
WHERE ScriptData='Marketing';
Is it even possible to do something like this when I have it converted from hex to text? I've tried so many different queries, most of which include subqueries, but all failed.
Converting it changes this
| ScriptID | RowOrder | ScriptData |
------------------------------------
| 5008 | 1 | 0x435669787|
to this (I'm over simplifying the results)
| ScriptID | RowOrder | ScriptData |
------------------------------------
| 5008 | 1 | Sales |
EDIT:
My best attempt seems to have been this query
UPDATE Script_Data
SET ScriptData='Engineering'
(SELECT ScriptID, RowOrder, CONVERT(varchar(max), ScriptData)
FROM Script_Data
WHERE ScriptData = 'Accounting')
But SQL is telling me that Implicit conversion from data type varchar to varbinary(max) is not allowed. Use the CONVERT function to run this query. I've tried to use CONVERT in creative ways to satisfy the error, but have not been successful. The ScriptData column is varbinary datatype with -1 length.
It seems you need to cast the new value to varbinary as part of the update.
UPDATE Script_Data SET
ScriptData = CAST('Engineering' AS VARBINARY(MAX))
WHERE CAST(ScriptData AS VARCHAR(MAX)) = 'Accounting'
I won't ask why you are storing strings as varbinary because I'm sure you realise life would be much easier if you just stored it as a varchar.
Here is the test script I used:
declare #ScriptData table (ScriptData varbinary(max));
insert into #ScriptData (ScriptData)
values (0x435669787), (convert(varbinary(max),'Sales'));
select *, convert(varchar(max),ScriptData,3), CAST(ScriptData AS varchar(MAX)) from #ScriptData;
update #ScriptData set
ScriptData = CAST('Marketing' AS VARBINARY(MAX))
where CAST(ScriptData AS varchar(MAX)) = 'Sales';
select *, convert(varchar(max),ScriptData,3), CAST(ScriptData AS varchar(MAX)) from #ScriptData;
For your SELECT query, the analogous UPDATE is to place conversion in the SET command assigning value to a new or different column, not the same column.
UPDATE is not a DDL (data definition language) but a DML (data manipulation language) command. Hence, it only adjusts data but does not change a columns' defined data type. Consider an ALTER command to create a new VARCHAR(MAX) column then run UPDATE to assign value:
ALTER TABLE Converted_SD ADD ScriptData_Text VARCHAR(MAX);
UPDATE Converted_SD
SET ScriptData_Text = CAST(CAST(ScriptData AS varbinary(MAX)) AS varchar(MAX));
Also, since ALTER is a DDL command, use it very sparingly and never in application code or stored procedure since it can adjust table schema and column definitions.

"9.67609e+008" values getting updated in the Temporary table column when inserting data from a table

I have created a temporary table and inserting data into the same. After fetching the data from the Temporary table the value for booking number column is updated as 9.67609e+008. The column has data type set to nvarchar. I should be getting the output as 967608505.
Expected output should be output as 967608505
Your problem might be the input datatype. Try this:
DECLARE #number FLOAT=967608505;
SELECT CAST(#number AS VARCHAR(100))
But you can avoid this by using an INT or BIGINT
SELECT CAST(CAST(#number AS BIGINT) AS VARCHAR(100))
In this answer you will find some details and links, in which cases a FLOAT is expressed in scientific notation by default.
You should use INT datatype to store int values:
DECLARE #yourValue INT = 967608505
SELECT #yourValue
Output:
967608505
UPDATE:
To store aplhanumeric values it is possible to use char, nchar and nvarchar or varchar.
Types such as char, nchar are used for very small values (e.g. 2 characters). nvarchar or varchar are used to store bigger values.
DECLARE #tbl TABLE
(
Foo nvarchar(50),
Bar nvarchar(50)
)
INSERT INTO #tbl
(
Foo
, Bar
)
VALUES
(N'967608505', '967608505' )
SELECT * FROM #tbl
OUTPUT:
Foo Bar
967608505 967608505
It looks like your input data is actually of type REAL or FLOAT, because for those types casting/converting to VARCHAR uses scientific notation.
You can avoid that from happening by using the T-SQL FORMAT() or STR() functions:
DECLARE #r REAL = 967608505 , #f FLOAT = 967608505
SELECT FORMAT(#r, '0') as [REAL-FMT] , FORMAT(#f, '0') as [FLOAT-FMT],
STR(#r ) as [REAL-STR] , STR(#f ) as [FLOAT-STR]
Result:
+-----------+-----------+-----------+-----------+
| REAL-FMT | FLOAT-FMT | REAL-STR | FLOAT-STR |
+-----------+-----------+-----------+-----------+
| 967608500 | 967608505 | 967608512 | 967608505 |
+-----------+-----------+-----------+-----------+
As you can see the REAL value suffers from last-digit issues due to insufficient internal accuracy.
All in all we can conclude that your input variable is (or should be) FLOAT, and then it is up to you to decide which function to use.
A possible pitfall is that STR() produces right-aligned output, padded with spaces on the left, which can be removed by doing LTRIM().

SQL server insert encoding

Using SQL Server 2012 Management studio,
running the following command insert the data but modify/convert the "," to another char who look like a comma but is not (char code 8128):
INSERT INTO [dbo].[MyTable] VALUES(3,'City','Qu,bec')
I tried the Prefix N but it didnt worked:
INSERT INTO [dbo].[MyTable] VALUES(3,'City',N'Qu,bec')
However, if i use the "Edit" mode of Management studio, the good value is inserted.
The data type of the column is nvarchar(100)
I think it has something to do about Encoding but I cant find how to fix it. In my C# project, I use LinqToSql to extract the data and I end with the bad char (char code 8128) if the data was inserted with the command instead of the "Edit" mode.
I would appreciate a fix and a short explanation. Thx
If you want to insert these values from code, then you would use the N prefix, and use the actual unicode character like so:
create table mytable (id int, type varchar(16), name nvarchar(64))
insert into mytable values (3,'City',N'Québec')
select * from mytable
rextester demo: http://rextester.com/JUBZS75211
returns:
+----+------+--------+
| id | type | name |
+----+------+--------+
| 3 | City | Québec |
+----+------+--------+

sql server 2012 express do not understand Russian letters

I have DB which is working with Russian text however when i run queries it shows me this. Database will used by Russians and it has to show Russian text properly!
Any ideas how to fix it? In the future it will located in Russia and work with Russian version SQL Server but right now I am working on English version SQL 2012 Express.
Here is the table and insert statement:
Create table Employee
(
EmpID int not null IDENTITY (10, 1),
StrName nvarchar (25) not null,
Phone1 nvarchar (25) not null,
Phone2 nvarchar (25)
Primary Key (EmpID),
);
insert into Employee (LastName , FirstName,Phone1,Phone2)
values ('Иванов','111 111 11111','111 111 1111');
Are you sure the data has been stored in the database correctly? How do you know?
Make sure that the column has a proper collation, that it is defined as nvarchar and that inserts of string literals are prefixed with N. For example, these are not the same:
INSERT dbo.table(column) SELECT 'foo';
INSERT dbo.table(column) SELECT N'foo';
As an example:
USE tempdb;
GO
CREATE TABLE dbo.foo
(
ID INT PRIMARY KEY,
bar NVARCHAR(32) COLLATE SQL_Ukrainian_CP1251_CI_AS
);
INSERT dbo.foo SELECT 1,'АБВГДЕЖЅZЗИІКЛ';
INSERT dbo.foo SELECT 2,N'АБВГДЕЖЅZЗИІКЛ';
SELECT ID, bar FROM dbo.foo;
GO
DROP TABLE dbo.foo;
Results:
ID bar
---- --------------
1 ????????Z?????
2 АБВГДЕЖЅZЗИІКЛ
And to show how this affects your insert statement, your string is missing the N prefix:
SELECT
CONVERT(NVARCHAR(32), 'Иванов'),
CONVERT(NVARCHAR(32), N'Иванов');
Results:
------ ------
?????? Иванов
So, prefix your Unicode strings with N'a prefix' or lose data.
While Aaron Bertrand gave a good explanation why do you getting such a results, I'd say there's a way not to prefix all you strings with russian letters with 'N'.
As far as I know, you have just set your server collation properly. So if you set your collation, for example, like Cyrillic_General_CI_AS, server could treat varchar with russian letters properly:
select
'español', '平成年月日', 'иван',
serverproperty('collation')
results:
espanol ????? иван Cyrillic_General_CI_AS
As you see, spanish and Chinese strings are not treated properly while russian strings are. So you can insert data into nvarchar columns without prefixing strings with 'N'
That said, I'm using nvarchar data type in our database as default strings, nvarchar parameters in stored procedures. I very rarely use russian strings in code (only when I want to test something), and I've never used N'string' syntax.
While having correct default collation could be handy, there's problem with this solution - it's not easy to change default collation on installed SQL Server, so you have to be careful when installing SQL Server instance and choose collation properly.