Using SQL Scripts, I need to validate Comma Separate value. How should i validate the String Variable ?
Validation should be both Right / Left Trim for each value and there should not be any special characters such as Comma or Period for the last value.
create table #test
(col varchar(100))
insert into #test values
('1,2'),
('1,2,'),
('1,'),
('1,2,3,4,5')
select * from #test
In the above query, for the second value - Expected Result is 1,2
In the above query, for the Third value - Expected Result is 1
You can update your table to fix "offensive" values.
update #test
set col = substring(col, 1, len(col) - 1)
where col not like '%[0-9]'
This will remove last character where value doesn't end by a digit.
You can use a check constraint. You seem to want something like this:
alter table t add constraint chk_name as
(name like '%,%' and
name not like '%,%,%' and
name not like '%[^a-zA-Z,]%'
)
SQL Server doesn't have support for regular expressions. This implements the rules:
Name has to have a comma
Name does not have two commas
Name consists only of alphabetic characters and a comma
You may find that you need slightly more flexibility, but this handles the cases in your question.
Related
I have a table in SQL Server that stores codes. Depending on the nomenclature, some begin with 'DB_' and others with 'DBL_'. I need a way to filter the ones that start with 'DB_', since when I try to do it, it returns all the results.
CREATE TABLE CODES(Id integer PRIMARY KEY, Name Varchar(20));
INSERT INTO CODES VALUES(1,'DBL_85_RC001');
INSERT INTO CODES VALUES(2,'DBL_85_RC002');
INSERT INTO CODES VALUES(3,'DBL_85_RC003');
INSERT INTO CODES VALUES(4,'DB_20_SE_RC010');
INSERT INTO CODES VALUES(5,'DB_20_SE_RC011');
SELECT * FROM CODES where Name like 'DB_%';
The result that returns:
1|DBL_85_RC001
2|DBL_85_RC002
3|DBL_85_RC003
4|DB_20_SE_RC010
5|DB_20_SE_RC011
Expected result:
4|DB_20_SE_RC010
5|DB_20_SE_RC011
_ is a wildcard for a single character in a LIKE expression. Thus both 'DB_' and 'DBL' are LIKE 'DB_'. If you want a literal underscore you need to put it in brackets ([]):
SELECT *
FROM CODES
WHERE [Name] LIKE 'DB[_]%';
The underscore is a wildcard in SQL Server. You can escape it:
where name like 'DB$_%' escape '$'
You could also use left():
where left(name, 3) = 'DB_'
However, this is not index- and optimizer friendly.
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.
Here are my queries:
(Won't return a value)
select * from T_VoucherHeaderEntry
where Vhe_VoucherNo = 'APV-1808-00160'
(Will return a value)
Select * from T_VoucherHeaderEntry where Vhe_VoucherNo like 'APV-1808-00160%'
I tried trimming my first query but it doesn't work.
You appear to have other control characters in your stored data, specifically carriage-return and line-feed. This highlights the issue and the final query finds all rows currently affected by this1:
;declare #t table (Val1 varchar(20))
insert into #t(Val1) values ('abc
'),('def')
select * from #t where Val1 = 'abc'
select * from #t where Val1 like 'abc%'
select * from #t where Val1 like '%
%'
So, fix those rows however you choose to do so. Next, add a CHECK constraint on this column:
ALTER TABLE T_VoucherHeaderEntry
ADD CONSTRAINT CK_T_VoucherHeaderEntry_NoExoticChars
CHECK (Vhe_VoucherNo not like '%[^-A-Za-z0-9]%')
(It's expressed as a double negative to say we want to disallow any character in the provided range. We have to put - as the first character so that it's interpreted literally and not as a range separator)
And finally update your applications to not attempt to insert such bogus data in the first place.
1The third query identifies those specifically affected by CR/LF issue. For a more general approach, once you've decided on the appropriate character range to specify in your check constraint, a variant of that same approach will find rows that won't satisfy the check constraint for you to fix.
if your Vde_VoucherNo column contain this 'APV-1808-00160' value then definitely below should work and return data
select * from T_VoucherHeaderEntry
where Vhe_VoucherNo = 'APV-1808-00160'
in case of white-space in your column value, you can use trim function
select * from T_VoucherHeaderEntry
where trim(Vhe_VoucherNo) = 'APV-1808-00160'
But if your column contain pattern of this values APV-1808-00160 then like will work which is your 2nd query
Select * from T_VoucherHeaderEntry
where Vhe_VoucherNo like 'APV-1808-00160%'
BTW noticed the two query is from two different table , so that may be also reason
I am using query as follows to get any records that begins with any character, has bunch of 0s and ends with number (1 in this case).
where column like '_%[0]1'
But the issue is it's even returning me d0101 etc. which I don't want. I just want d0001, or r0001. Can I use it to exactly match pattern, not partially using like?
Any other options in ms-sql?
SQL-Server does not really do proper regular expressions but you can generate the search clause you want like this:
where column like '_%1' and column not like '_%[^0]%1'
The second condition will exclude all cases where you have a character other than 0 in the middle of the string.
It will allow strings of all possible lengths, provided they start with an arbitrary character, then have any number of 0s and finish with a 1. All other strings will not satisfy the where clause.
create table tst(t varchar(10));
insert into tst values('d0101');
insert into tst values('d0001');
insert into tst values('r0001');
select * from tst where PATINDEX('%00%1', t)>0
or
select * from tst where t like '%00%1'
You use the _ to say that you don't care what char is there (single char) and then use the rest of the string you want:
DECLARE # TABLE (val VARCHAR(100))
INSERT INTO #
VALUES
('d0001'),
('f0001'),
('e0005'),
('e0001')
SELECT *
FROM #
WHERE val LIKE '_0001'
This code only really handles your two simple examples. If it is more complex, add it to your post.
I want to check a column for a special sign with regular expression, but not all special sign. I want all sign that are not letter, number and not ,+.-& (blank) .I try this
where column like '%[^((a-z)(A-Z)(0-9)(,\+\.\-)(\&)( ))]%'
same like this
where column like '%[^0-9a-zA-Z ,\-+\.\& ]%'
But if I try this Statement, I get strings with - and speziell blank.
result1: 't-est regex'
result2: ' TestJ. '
Have you any idea why?
Thx for the help.
The LIKE operator isn't exactly using the regex syntax.
It's way more simplified.
But some things are still possible.
This LIKE would get what you want:
where [column] like '%[^A-Za-z0-9 &.,+-]%'
Note that the class negation ^ does work.
And it's best to put a - at the end of a class. So it's not mistaken to be used for a range of characters.
There's no concept for capture groups in a LIKE, so the ( and ) were removed.
But if you also want the LIKE to ignore the brackets, just add them to the character class.
(even in regex you don't have capture groups inside a character class anyway)
The LIKE operation is case-insensitive when the COLLATION of the character field is case-insensitive.
Which seems to be the default on most databases.
So most of the times, a LIKE '%[A-Z]%' and LIKE '%[A-Za-z]%' would behave the same.
Example snippet:
-- using a Case-Sensitive collation for the varchar.
declare #T table (id int identity(1,1), col varchar(30) COLLATE Latin1_General_CS_AS);
insert into #T (col) values
('abc123'),
('ABC & 123'),
('abc123 &.,+-'),
('abc-123 #');
select * from #T where col like '%[^A-Za-z0-9 &.,+-]%';
Returns:
id col
-- ---------
4 abc-123 #