I am using double quotes in my column names because my source data has fields with the same name but different capitalization. Therefore I am adding double quotes to my column names to distinguish them.
INSERT INTO ... does not work in honoring the double quoted column names.
create table CAPS_CHECK
(
"abc" string,
"ABC" string,
def string
);
insert into CAPS_CHECK
VALUES ( 'x', 'y', 'z' );
insert into CAPS_CHECK ("abc")
VALUES ( 'q' );
insert into CAPS_CHECK ("ABC")
VALUES ( 'r' );
Everything up to here works as expected (and the INSERT was able to distinguish between "abc" and "ABC"), but
insert into CAPS_CHECK ("abc", "ABC")
VALUES ( 'a', 'b' );
returns
SQL compilation error: duplicate column name 'ABC'
How can I distinguish between those column names so that I can use them both in the same INSERT statement?
(Note that the same problem happens with COPY INTO ...)
Related
I have a column A which contains comma separated values for ex. "5,6,7"
and another column B contain "5".
I have to compare column B value with column A value and replace with a certain value. In this case i want to replace "5,6,7" with "8,6,7".
Is this possible with Sql server
Thank you.
You can use STRING_SPLIT to split up the values, then REPLACE and STRING_AGG to reaggregate
SELECT B = (
SELECT STRING_AGG(REPLACE(value, '5', '8'), ',')
FROM STRING_SPLIT(YourTable.A, ',')
)
FROM YourTable;
I am inserting data from one table to another so when inserting I got above error mentioned in title
Insert into dbo.source(
title
)
Select
Title from dbi.destination
title in dbo.source table is of INT data type and title in dbo.destination table is of Varchar data type and I have data like abc, efg, etc. in the dbo.destination table.
So how to solve this now or is it possible to convert and insert values?
You can use SQL Server try_cast() function as shown below. Here is the official documentation of TRY_CAST (Transact-SQL).
It Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
Syntax
TRY_CAST ( expression AS data_type [ ( length ) ] )
And the implementation in your query.
INSERT INTO dbo.source (title)
SELECT try_cast(Title AS INT)
FROM dbi.destination
Using this solution you need to be sure you have set the column allow null true otherwise it will give error.
If you do not want to set the allow null then you need minor changes in select query as shown below - passing the addition criteria to avoid null values.
Select ... from ... where try_cast(Title AS INT) is not null
You must use isnumeric method of SQL for checking is data numeric or not
CONVERT(INT,
CASE
WHEN IsNumeric(CONVERT(VARCHAR(12), a.value)) = 1 THEN CONVERT(VARCHAR(12),a.value)
ELSE 0 END)
Think about your data types - obviously you cannot have a text string like 'abc' in a column that is defined to hold integers.
It makes no sense to copy a string value into an integer column, so you have to confirm how you want to handle these - do you simply discard them (what is the impact of throwing data away?) or do you replace them with some other value?
If you want to ignore them and use NULL in place then use:
INSERT dbo.Source (Title)
SELECT CASE
WHEN ISNUMERIC(Title) = 1 THEN CAST(Title as INT)
ELSE NULL
END
FROM dbo.Destination
If you want to replace the value then simply change NULL above to the value you want e.g. 0
You can use regex to root out non numeric characters
Insert into dbo.source(
title
)
Select
case when Title not like '%[^0-9]%' then null else cast(Title as int) end as Title
from dbi.destination
Just filter only numeric field from destination table like as below:
Insert into dbo.source(
title
)
Select
Title from dbi.destination
where ISNUMERIC(Title) = 1
My goal is to enforce case-insensitive uniqueness on a column that may contain unicode characters on any unicode planes. But I encountered some inconsistent behavior when testing against SQL Server 2014(build 12.0.4213.0). Here is the test:
CREATE TABLE unicodetest1 (
id int,
/* this collation is supposed to support all supplementary unicode characters */
a nvarchar(10) COLLATE Latin1_General_100_CI_AS_SC
);
CREATE UNIQUE INDEX idx_a_1 ON unicodetest1(a);
I can insert many single unicode characters, both on BMPs and SMP (Plane 1):
INSERT INTO unicodetest1(id, a) VALUES(1, 't'); -- U+0074
INSERT INTO unicodetest1(id, a) VALUES (100, N'👸'); -- U+1F478
INSERT INTO unicodetest1(id, a) VALUES (101, N'👹'); -- U+1F479
INSERT INTO unicodetest1(id, a) VALUES (104, N'⭐'); -- U+2b50
SELECT id, a, len(a) FROM unicodetest1;
The length of the single character strings is 1, which is expected.
When I concatenate some unicode characters to ascii strings, it still works:
INSERT INTO unicodetest1(id, a) VALUES (111, N'test'); -- ok
INSERT INTO unicodetest1(id, a) VALUES (112, N'test👸'); -- ok
INSERT INTO unicodetest1(id, a) VALUES (113, N'test👹'); -- ok
So far so good.
But, when I insert N'test⭐', I get a duplicate key violation:
INSERT INTO unicodetest1(id, a) VALUES (114, N'test⭐'); -- dup
Msg 2601, Level 14, State 1, Line 21
Cannot insert duplicate key row in object 'dbo.unicodetest1' with unique index 'idx_a_1'. The duplicate key value is (test⭐).
The character "⭐" has a code point U+2b50, it is on BMP!
It seems that SQL Server thinks N'test⭐' and N'test' are identical!
My question is: what makes "⭐" special that it violates uniqueness constraint when it is concatenated to a string?
Thanks
James
SQL Server Standard 64 Bit with collation SQL_Latin1_General_CP1_CS_AS
Table plz:
ort varchar(30) SQL_Latin1_General_CP1_CS_AS
select ort,
from plz
where
ort >= 'zürich'
and ort <= 'zürichz'
Selects this data:
Zürich
Zürich Mülligen
Zürich 80
Without the z at the end of second zürich no data are selected which is ok. But why does it show data on case sensitive server?
There are two confusions happening here:
Equality vs Sorting
When using the equality operator = the issue of case-sensitivity is more straight-forward and obvious (e.g. "z" <> "Z"). But when using the > and < operators sorting is required and this is separate from, though influenced by, case-sensitive vs case-insensitive. Sorting is determined first by which type of ordering (see next point) and then possibly determined by case-sensitivity.
Dictionary order vs Binary (i.e. ASCII value / Code Point) order
Dictionary ordering, the default, means that a particular languages alphabetical ordering will be used. The particular language is part of the collation name, such as Latin1_General or Danish. This will put "a" (ASCII = 97) and "A" (ASCII = 65) together and "Z" (ASCII = 90) after both. A binary collation (i.e. one ending in _BIN or _BIN2) will use the binary character value, which will put "Z" between "A" and "a". A binary ordering is necessarily case-sensitive as it is everything-sensitive. A dictionary ordering will group "A" and "a" together, but it will only enforce that "A" comes before "a" if the collation is also case-sensitive. A case-insensitive dictionary ordering can intermix "A" and "a" values (see final SELECT in the example).
Now let's tie this all back to the question. The current collation is SQL_Latin1_General_CP1_CS_AS which is a Dictionary ordering. And when looking in a dictionary, both Zürich and zürich are going to be found back-to-back; Zürich would not come before zany simply because it has a capital Z.
Looking at the results returned by your query, the first entry, Zürich should not be there. I cannot get that to be returned. Since this is a case-sensitive collation, Zürich does come before zürich and would be filtered out by the WHERE clause. But the other two values, Zürich Mülligen and Zürich 80 are valid to be returned as they do match the WHERE clause. If you want them to not match, then you need to use a binary collation instead of the case-sensitive dictionary one.
To see this in action, run the following:
Dictionary (Case-InSensitive):
SELECT tmp.val
FROM (SELECT 'bat'
UNION ALL
SELECT 'bar'
UNION ALL
SELECT 'bad'
UNION ALL
SELECT 'Bar') tmp(val)
ORDER BY tmp.val COLLATE SQL_Latin1_General_CP1_CI_AS ASC;
Results:
bad
bar
Bar -- "Bar" typically, but not necessarily, comes after "bar"
bat
Dictionary (Case-Sensitive):
SELECT tmp.val
FROM (SELECT 'bat'
UNION ALL
SELECT 'bar'
UNION ALL
SELECT 'bad'
UNION ALL
SELECT 'Bar') tmp(val)
ORDER BY tmp.val COLLATE SQL_Latin1_General_CP1_CS_AS ASC;
Results:
bad
Bar -- "Bar" necessarily comes before "bar", but not before "bad, or even "b"
bar
bat
Binary:
SELECT tmp.val
FROM (SELECT 'bat'
UNION ALL
SELECT 'bar'
UNION ALL
SELECT 'bad'
UNION ALL
SELECT 'Bar') tmp(val)
ORDER BY tmp.val COLLATE Latin1_General_BIN2 ASC;
Results:
Bar -- "Bar" ("B" value = 66) necessarily comes before "b" (value = 98)
bad
bar
bat
To get a better sense of how case-sensitivity affects filtering and sorting in general, run the following step-by-step example.
DECLARE #test TABLE (string VARCHAR(30)
COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL);
INSERT INTO #test (string) values ('A');
INSERT INTO #test (string) values ('B');
INSERT INTO #test (string) values ('Y');
INSERT INTO #test (string) values ('Z');
INSERT INTO #test (string) values ('a');
INSERT INTO #test (string) values ('b');
INSERT INTO #test (string) values ('y');
INSERT INTO #test (string) values ('z');
-- case-sensitive, dictionary ordered sorting via column collation
SELECT [string] AS [Test1] FROM #test ORDER BY string ASC;
/* -- upper-case and lower-case of each letter are grouped together;
-- upper-case consistently comes first due to case-sensitive
A
a
B
b
Y
y
Z
z
*/
-- case-sensitive comparison via column collation
SELECT [string] AS [Test2] FROM #test WHERE string = 'Y';
/* -- equality is straight-forward when using case-sensitive comparison
Y
*/
-- case-sensitive, dictionary ordered comparison and sorting via column collation
SELECT [string] AS [Test3] FROM #test WHERE string >= 'Y' ORDER BY string ASC;
/* -- upper-case comes first due to case-sensitive
Y
y
Z
z
*/
-- case-sensitive, dictionary ordered comparison and sorting via column collation
SELECT [string] AS [Test4] FROM #test WHERE string >= 'y' ORDER BY string ASC;
/* -- upper-case comes first due to case-sensitive
y
Z
z
*/
-- case-insensitive, dictionary ordered comparison via collation override
SELECT [string] AS [Test5] FROM #test
WHERE string > 'Y' COLLATE SQL_Latin1_General_CP1_CI_AS;
/* -- upper-case and lower-case are the same due to case-INsensitive
Z
z
*/
-- binary ordering via collation override
SELECT [string] AS [Test6] FROM #test ORDER BY string COLLATE Latin1_General_BIN ASC;
/*
A
B
Y
Z
a
b
y
z
*/
-- case-sensitive, dictionary ordered comparison via column collation;
-- binary ordering via collation override
SELECT [string] AS [Test7] FROM #test WHERE string >= 'y'
ORDER BY string COLLATE Latin1_General_BIN ASC;
/* -- lower-case 'y' comes before both 'Z' and 'z' when using a dictionary comparison
Z
y
z
*/
-- binary comparison via collation override;
-- binary ordering via collation override
SELECT [string] AS [Test8] FROM #test WHERE string >= 'y' COLLATE Latin1_General_BIN
ORDER BY string COLLATE Latin1_General_BIN ASC;
/* -- lower-case 'y' comes after all capitals when using a binary comparison
y
z
*/
-- case-insensitive, dictionary ordered sorting via collation override
SELECT [string] AS [Test9] FROM #test
ORDER BY string COLLATE SQL_Latin1_General_CP1_CI_AS ASC;
/* -- upper-case and lower-case of each letter are grouped together,
-- but inconsistent for upper-case vs lower-case first
A
a
b
B
Y
y
z
Z
*/
See the following links for some SQL Server collation info:
SQL Server Collation Name
Selecting a SQL Server Collation
When comparing strings, one of the first things that SQL Server does is to pad the shorter string with spaces so that the strings are of the same length. So basically you're query is trying to find any strings that match zürich and then the next character must be one that can appear between (from your first string) and z (from your second string) - which includes itself and most alphabetical characters.
This has nothing to do with case-sensitivity.
Without the z in your second string, the only strings that will match are those with the value zürich and just trailing spaces.
The accepted answer to this question claims that using a char column will preserve all filling spaces in a string in Sybase, but that is not the behavior I am seeing (unless I'm mistaken about what 'filling spaces' means). For example, when I run the following script:
create table #check_strings
(
value char(20) null
)
insert into #check_strings values (null)
insert into #check_strings values ('')
insert into #check_strings values (' ')
insert into #check_strings values (' ')
insert into #check_strings values ('blah')
insert into #check_strings values ('blah ')
insert into #check_strings values ('blah ')
insert into #check_strings values (' blah ')
select value, len(value) from #check_strings
I get the following output:
[NULL] - [NULL]
[single space] - 1
[single space] - 1
[single space] - 1
blah - 4
blah - 4
blah - 4
[four spaces]blah - 8
Is there any way to get Sybase to not strip off trailing spaces? Additionally, is there any way to get it to save an empty string as an empty string, and not as a single space?
I'm using Sybase 15.5.
To have fixed length on char columns, you must use the not null attribute.
For variable length columns, use varchar or char with a null attribute.
Then to measure the real data size use the datalength function not the len function nor the charlength function.
See http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sqlug/html/sqlug/sqlug208.htm
"When you create a char, unichar, or nchar column that allows nulls, Adaptive Server converts it to a varchar, univarchar, or nvarchar column and uses the storage rules for those datatypes."
Please, check not null column.