SQL server insert encoding - sql

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 |
+----+------+--------+

Related

Query on how to replace numerical data from a string/column

I have values in my column as below. Can anyone help me with how to replace any numeric data present in a column or string to blank using SQL Server query?
Below is the column data. How do I replace the numbers to blank and display only underscores.
You could approach this by counting the number of underscores, and then generating a string containing this number of underscores:
SELECT Column1, REPLICATE('_', LEN(Column1) - LEN(REPLACE(Column1, '_', '')))
FROM yourTable;
Demo
Here is a more generic solution. It will handle not just the underscore chars. It will work starting from SQL Server 2017 onwards.
As #Squirrel correctly mentioned, the TRANSLATE() function is very handy for such cases.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, col VARCHAR(256));
INSERT INTO #tbl (col) VALUES
('2413347_6752318'),
('7263_872_767'),
('123Code456');
-- DDL and sample data population, end
SELECT col AS [Before]
, REPLACE(TRANSLATE(col, '0123456789', SPACE(10)), SPACE(1), '') AS [After]
FROM #tbl;
Output
+-----------------+-------+
| Before | After |
+-----------------+-------+
| 2413347_6752318 | _ |
| 7263_872_767 | __ |
| 123Code456 | Code |
+-----------------+-------+

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.

Ukrainian character change to question mark when insert to table

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.

SQL UPDATE specific characters in string

I have a column with the following values (there is alot more):
20150223-001
20150224-002
20150225-003
I need to write an UPDATE statement which will change the first 2 characters after the dash to 'AB'. Result has to be the following:
20150223-AB1
20150224-AB2
20150225-AB3
Could anyone assist me with this?
Thanks in advance.
Use this,
DECLARE #MyString VARCHAR(30) = '20150223-0000000001'
SELECT STUFF(#MyString,CHARINDEX('-',#MyString)+1,2,'AB')
If there is a lot of data, you could consider to use .WRITE clause. But it is limited to VARCHAR(MAX), NVARCHAR(MAX) and VARBINARY(MAX) data types.
If you have one of the following column types, the .WRITE clause is easiest for this purpose, example below:
UPDATE Codes
SET val.WRITE('AB',9,2)
GO
Other possible choice could be simple REPLACE:
UPDATE Codes
SET val=REPLACE(val,SUBSTRING(val,10,2),'AB')
GO
or STUFF:
UPDATE Codes
SET val=STUFF(val,10,2,'AB')
GO
I based on the information that there is always 8 characters of date and one dash after in the column. I prepered a table and checked some solutions which were mentioned here.
CREATE TABLE Codes(val NVARCHAR(MAX))
INSERT INTO Codes
SELECT TOP 500000 CONVERT(NVARCHAR(128),GETDATE()-CHECKSUM(NEWID())%1000,112)+'-00'+CAST(ABS(CAST(CHECKSUM(NEWID())%10000 AS INT)) AS NVARCHAR(128))
FROM sys.columns s1 CROSS JOIN sys.columns s2
I run some tests, and based on 10kk rows with NVARCHAR(MAX) column, I got following results:
+---------+------------+
| Method | Time |
+---------+------------+
| .WRITE | 28 seconds |
| REPLACE | 30 seconds |
| STUFF | 15 seconds |
+---------+------------+
As we can see STUFF looks like the best option for updating part of string. .WRITE should be consider when you insert or append new data into string, then you could take advantage of minimall logging if the database recovery model is set to bulk-logged or simple. According to MSDN articleabout UPDATE statement: Updating Large Value Data Types
According to the OP Comment:-
Its always 8 charachters before the dash but the characters after the
dash can vary. It has to update the first two after the dash.
use the next simple code:-
DECLARE #MyString VARCHAR(30) = '20150223-0000000001'
SELECT REPLACE(#MyString,SUBSTRING(#MyString,9,3),'-AB')
Result:-
20150223-AB00000001
try,
update table set column=stuff(column,charindex('-',column)+1,2,'AB')
Declare #Table1 TABLE (DateValue Varchar(50))
INSERT INTO #Table1
SELECT '20150223-000000001' Union all
SELECT '20150224-000000002' Union all
SELECT '20150225-000000003'
SELECT DateValue,
CONCAT(SUBSTRING(DateValue,0,CHARINDEX('-',DateValue)),
REPLACE(LEFT(SUBSTRING(DateValue,CHARINDEX('-',DateValue)+1,Len(DateValue)),2),'00','-AB'),
SUBSTRING(DateValue,CHARINDEX('-',DateValue)+1,Len(DateValue))) AS ExpectedDateValue
FROM #Table1
OutPut
DateValue ExpectedDateValue
---------------------------------------------
20150223-000000001 20150223-AB000000001
20150224-000000002 20150224-AB000000002
20150225-000000003 20150225-AB000000003
To Update
Update #Table1
SEt DateValue= CONCAT(SUBSTRING(DateValue,0,CHARINDEX('-',DateValue)),
REPLACE(LEFT(SUBSTRING(DateValue,CHARINDEX('-',DateValue)+1,Len(DateValue)),2),'00','-AB'),
SUBSTRING(DateValue,CHARINDEX('-',DateValue)+1,Len(DateValue)))
From #Table1
SELECT * from #Table1
OutPut
DateValue
-------------
20150223-AB000000001
20150224-AB000000002
20150225-AB000000003

Insert a empty string on SQL Server with BULK INSERT

Example table contains the fields Id (the Identity of the table, an integer); Name (a simple attribute that allows null values, it's a string)
I'm trying a CSV that contains this:
1,
1,""
1,''
None of them gives me a empty string as the result of the bulk insertion. I'm using SQL Server 2012.
What can I do?
As far as I know, bulk insert can't insert empty string, it can either keep null value or use default value with keepnulls option or without keepnulls option. For your 3 sample records, after insert database, it should be like:
| id | name
| 1 | NULL
| 1 | ""
| 1 | ''
The reason is, the bulk insert will treat your first row, second column value as null; for other 2 rows, will take the second column value as not null, and take it as it is. Instead of let Bulk Insert to insert empty string value for you, you can let you table column having default value as empty string.
Example as following:
CREATE TABLE BulkInsertTest (id int, name varchar(10) DEFAULT '')
Bulk Insert same CSV file into table
BULK INSERT Adventure.dbo.BulkInsertTest
FROM '....\test.csv'
WITH
(
FIELDTERMINATOR ='\,',
ROWTERMINATOR ='\n'
)
SELECT * FROM BulkInsertTest
The result will be like following: (The first row in your CSV will get an empty string)
| id | name
| 1 |
| 1 | ""
| 1 | ''
Please bear in mind that the specified DEFAULT value will only get inserted if you are not using the option KEEPNULLS.
Using the same example as above, if you add the option KEEPNULLS to the BULK INSERT, i.e.:
BULK INSERT BulkInsertTest
FROM '....\test.csv'
WITH
(
FIELDTERMINATOR ='\,',
ROWTERMINATOR ='\n',
KEEPNULLS
)
will result in the default column value being ignored and NULLs being inserted fro empty strings, i.e:
SELECT * FROM BulkInsertTest
will now give you:
id name
1 NULL
1 ""
1 ''
There does not seem to be a good reason to add KEEPNULLS this in your example, but I came across a similar problem just now, where KEEPNULLS was required in the BULK INSERT.
My solution was to define make the column [name] in the staging table BulkInsertTest NOT NULL but remember that the DEFAULT column value gets ignored and an empty string gets inserted instead.
See more here : Keep Nulls or UseDefault Values During Bulk Import (SQL Server)