Oracle varchar2 equivalent in sql server - sql

create table #temp(name nvarchar(10))
insert into #temp values('one')
select * from #temp where name = 'one'
select * from #temp where name = 'one ' --one with space at end
drop table #temp
In the above I have used nvarchar for name.
My requirement is the result should be exist for the first select query, and it should not return for 2nd query. Do not trim the name. Advise me which data type can I use for this in sql server?

Its not the data type that can resolve this issue. You need to see this article:
INF: How SQL Server Compares Strings with Trailing Spaces
SQL Server follows the ANSI/ISO SQL-92 specification (Section 8.2,
, General rules #3) on how to compare strings
with spaces. The ANSI standard requires padding for the character
strings used in comparisons so that their lengths match before
comparing them. The padding directly affects the semantics of WHERE
and HAVING clause predicates and other Transact-SQL string
comparisons. For example, Transact-SQL considers the strings 'abc' and
'abc ' to be equivalent for most comparison operations.
There are several ways to overcome this, one is to use Like.
select * from #temp where name like 'one ' --one with space at end
This will return no result.
You should see this blog post: Testing strings for equality counting trailing spaces by AnthonyBloesch

Related

How to Extract only numbers from the String without using function in SQL

Table contains data as below
Table Name is REGISTER
Column Name is EXAM_CODE
Values like ('S6TJ','S7','S26','S24')
I want answer like below
Result set - > (6,7,26,24)
Please suggest solution - since regexp_replace is not recognized built in function name in SQL.
The complexity of the answer depends on two things: the RDBMS used and whether the numbers in the EXAM_CODE are contiguous.
I have assumed that the RDBMS is SQL Server and the numbers in EXAM_CODE are always contiguous. If not, please advise and I can revise the answer.
The following SQL shows a way of accomplishing the above using PATINDEX.:
CREATE TABLE #REGISTER (EXAM_CODE VARCHAR(10));
INSERT INTO #REGISTER VALUES ('S6TJ'),('S7'),('S26'),('S24');
SELECT LEFT(EXAM_CODE, PATINDEX('%[^0-9]%', EXAM_CODE) - 1)
FROM (
SELECT RIGHT(EXAM_CODE, LEN(EXAM_CODE) - PATINDEX('%[0-9]%', EXAM_CODE) + 1) + 'A' AS EXAM_CODE
FROM #REGISTER
) a
DROP TABLE #REGISTER
This outputs:
6
7
26
24
PATINDEX matches a specified pattern against a string (or returns 0 if there is no match).
Using this, the inner query fetches all of the string AFTER the first occurence of a number. The outer query then strips any text that may appear on the end of the string.
Note: The character A is appended to the result of the inner query in order to ensure that the PATINDEX check in the outer query will make a match. Otherwise, PATINDEX would return 0 and an error would occur.

Differentiate Exponents in T-SQL

In SQL Server 2017 (14.0.2)
Consider the following table:
CREATE TABLE expTest
(
someNumbers [NVARCHAR](10) NULL
)
And let's say you populate the table with some values:
INSERT INTO expTest VALUES('²', '2')
Why does the following SELECT return both rows?
SELECT *
FROM expTest
WHERE someNumbers = '2'
Shouldn't nvarchar realize that '²' is unicode, while '2' is a separate value? How (without using the UNICODE() function) could I identify this data as being nonequivalent?
Here is a db<>fiddle. This shows the following:
Your observation is true even when the values are entered as national character set constants.
The "ASCII" versions of the characters are actually different.
The problem goes away with a case-sensitive collation.
I think the exponent is just being treated as a different "case" of the number, so they are considered the same in a case-insensitive collation.
The comparison is what you expect with a case-sensitive collation.

Include wildcards in sql server in the values themselves - not when searching with LIKE

Is there a way to include wildcards in sql server in the values themselves - not when searching with LIKE?
I have a database that users search on. They search for model numbers that contain different wildcard characters but do not know that these wildcard characters exist.
For example, a model number may be 123*abc in the database, but the user will search for 1234abc because that's what they see for their model number on their unit at home.
I'm looking for a way to allow users to search without knowledge of wildcards but have a systematic way to include model numbers with wildcard characters in the database.
What you could do is add a PERSISTED computed column to your table with valid pattern expression for SQL Server. You stated that * should be any letter or numerical character, and comma delimited values in parenthesis can be any one of those characters. Provided that commas don't appear in your main data, nor parenthesis, then this should work:
USE Sandbox;
GO
CREATE TABLE SomeTable (SomeString varchar(15));
GO
INSERT INTO SomeTable
VALUES('123abc'),
('abc*987'),
('def(q,p,r,1)555');
GO
ALTER TABLE SomeTable ADD SomeString_Exp AS REPLACE(REPLACE(REPLACE(REPLACE(SomeString,'*','[0-9A-z]'),'(','['),')',']'),',','') PERSISTED; --What you're interested in
SELECT *
FROM SomeTable;
GO
DECLARE #String varchar(15) = 'defp555';
SELECT *
FROM SomeTable
WHERE #String LIKE SomeString_Exp; --And how to search
GO
DROP TABLE SomeTable;
If * is any character, and noy any alphanumeric then you could shorten the whole thing to (and provided your on SQL Server 2017):
ALTER TABLE SomeTable ADD SomeString_Exp AS REPLACE(TRANSLATE(SomeString,'*()','_[]'),',','') PERSISTED;
I'm thinking either:
where #model_number like replace(model_number, '*', '%')
or
where #model_number like replace(model_number, '*', '_')
Depending on whether '*' means any string (first example) or exactly one character (second example).

Allow trailing white space differences in SQL Server unique constraint [duplicate]

I'm using Microsoft SQL Server 2008 R2 (with latest service pack/patches) and the database collation is SQL_Latin1_General_CP1_CI_AS.
The following code:
SET ANSI_PADDING ON;
GO
CREATE TABLE Test (
Code VARCHAR(16) NULL
);
CREATE UNIQUE INDEX UniqueIndex
ON Test(Code);
INSERT INTO Test VALUES ('sample');
INSERT INTO Test VALUES ('sample ');
SELECT '>' + Code + '<' FROM Test WHERE Code = 'sample ';
GO
produces the following results:
(1 row(s) affected)
Msg 2601, Level 14, State 1, Line 8
Cannot insert duplicate key row in object 'dbo.Test' with unique index 'UniqueIndex'. The duplicate key value is (sample ).
The statement has been terminated.
‐‐‐‐‐‐‐‐‐‐‐‐
>sample<
(1 row(s) affected)
My questions are:
I assume the index cannot store trailing spaces. Can anyone point me to official documentation that specifies/defines this behavior?
Is there a setting to change this behavior, that is, make it recognize 'sample' and 'sample ' as two different values (which they are, by the way) so both can be in the index.
Why on Earth is the SELECT returning a row? SQL Server must be doing something really funny/clever with the spaces in the WHERE clause because if I remove the uniqueness in the index, both INSERTs will run OK and the SELECT will return two rows!
Any help/pointer in the right direction would be appreciated. Thanks.
Trailing blanks explained:
SQL Server follows the ANSI/ISO SQL-92 specification (Section 8.2,
, General rules #3) on how to compare strings
with spaces. The ANSI standard requires padding for the character
strings used in comparisons so that their lengths match before
comparing them. The padding directly affects the semantics of WHERE
and HAVING clause predicates and other Transact-SQL string
comparisons. For example, Transact-SQL considers the strings 'abc' and
'abc ' to be equivalent for most comparison operations.
The only exception to this rule is the LIKE predicate. When the right
side of a LIKE predicate expression features a value with a trailing
space, SQL Server does not pad the two values to the same length
before the comparison occurs. Because the purpose of the LIKE
predicate, by definition, is to facilitate pattern searches rather
than simple string equality tests, this does not violate the section
of the ANSI SQL-92 specification mentioned earlier.
Here's a well known example of all the cases mentioned above:
DECLARE #a VARCHAR(10)
DECLARE #b varchar(10)
SET #a = '1'
SET #b = '1 ' --with trailing blank
SELECT 1
WHERE
#a = #b
AND #a NOT LIKE #b
AND #b LIKE #a
Here's some more detail about trailing blanks and the LIKE clause.
Regarding indexes:
An insertion into a column whose values must be unique will fail if you supply a value that is differentiated from existing values by
trailing spaces only. The following strings will all be considered
equivalent by a unique constraint, primary key, or unique index.
Likewise, if you have an existing table with the data below and try to
add a unique restriction, it will fail because the values are
considered identical.
PaddedColumn
------------
'abc'
'abc '
'abc '
'abc '
(Taken from here.)

Reading Unicode strings from SQL Server

I know strings need to be prefixed with N' in SQL Server (2012) INSERT statements to store them as UNICODE but do they have to be retrieved (SELECT statement) in a certain way as well so they are in UNICODE?
I am able to store international strings correctly with N notation but when I run SELECT query to fetch the records back, it comes as question marks. My query is very simple.
SELECT COLUMN1, COLUMN2 FROM TABLE1
I am looking at other possible reasons that may have caused this issue but at least I want to eliminate the SQL statement above. Should it read COLUMN1 and COLUMN2 columns correctly when they both store UNICODE strings using N notation? Do I have to do anything to the statement to tell it they are UNICODE?
Within management studio you should not need to do anything special to display the correct values. Make sure that the columns in your table is defined as Unicode strings NVARCHAR instead of ANSI strings VARCHAR.
The following example demonstrates the concept:
CREATE TABLE UnicodeExample
(
MyUnicodeColumn NVARCHAR(100)
,MYANSIColumn VARCHAR(100)
)
INSERT INTO UnicodeExample
(
MyUnicodeColumn
,MYANSIColumn
)
VALUES
(
N'איש'
,N'איש'
)
SELECT *
FROM UnicodeExample
DROP TABLE UnicodeExample
In the above example the column MyUnicodeColumn is defined as an NVARCHAR(100) and MYANSIColumn is defined as a VARCHAR(100). The query will correctly return the result for MyUnicodeColumn but will return ??? for MYANSIColum.