我想创建一个验证网址的CHECK CONSTRAINT
。
这是我的第一种方法,但它也需要标签。
CHECK ([ServiceURL] LIKE 'https://[a-z0-9]%.[a-z0-9]%')
另一个想法是这个
CHECK ([ServiceURL] LIKE 'https://[a-z0-9].[a-z0-9]')
但这不起作用。任何想法?
答案 0 :(得分:3)
进一步采用Gary的例子,下面的版本显示了我们如何在不使用游标的情况下编写函数以及如何将check约束添加到表中。你可能想要扩展它来处理http和https,以及可能的其他修改(比如允许/字符)
CREATE FUNCTION dbo.IsValidURL (@Url VARCHAR(200))
RETURNS INT
AS
BEGIN
IF CHARINDEX('https://', @url) <> 1
BEGIN
RETURN 0; -- Not a valid URL
END
-- Get rid of the http:// stuff
SET @Url = REPLACE(@URL, 'https://', '');
-- Now we need to check that we only have digits or numbers
IF (@Url LIKE '%[^a-zA-Z0-9]%')
BEGIN
RETURN 0;
END
-- It is a valid URL
RETURN 1;
END
-- Create the table
CREATE TABLE dbo.MyTableOnlyLettersAndDigits
(
id int identity(1,1) primary key clustered,
ServiceURL varchar(200) not null
);
GO
-- Add the check constraint
ALTER TABLE dbo.MyTableOnlyLettersAndDigits
ADD CONSTRAINT chkValidURLs CHECK (dbo.IsValidURL(ServiceURL) = 1);
-- Some tests to show it works
insert into dbo.MyTableOnlyLettersAndDigits(ServiceURL)
values ('Missing prefix.Invalid');
insert into dbo.MyTableOnlyLettersAndDigits(ServiceURL)
values ('https://IamAValidURL123');
insert into dbo.MyTableOnlyLettersAndDigits(ServiceURL)
values ('https://Invalid#Char');
答案 1 :(得分:1)
like子句的模式匹配非常有限,如您所发现的那样。无法使用类似子句重现您想要的行为。
您可以将自己的模式匹配功能作为CLR过程进行滚动。您也可以在TSQL中执行此等效逻辑,因为逻辑不像UDF那么复杂。然后在检查约束(或触发器等)中使用UDF
这是article for UDF for URL validation,其功能如下。我没有亲自测试过。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[IsValidUrl]
(
@Url varchar(100)
)
RETURNS int
AS
BEGIN
-- CREATE THE VARIABLES
DECLARE @TldExtension VARCHAR(10)
-- CLEAN THE URL
SET @Url = (SELECT REPLACE(@Url,'http://',''))
IF (CHARINDEX('/', @Url) !=0)
SET @Url = SUBSTRING(@Url, 0, CHARINDEX('/', @Url))
-- DECLARE THE CURSOR
DECLARE Tld_Cursor CURSOR FOR
SELECT [Tld] FROM [kogd].[dbo].[TLD]
ORDER BY [Length] DESC
-- OPEN THE CURSOR
OPEN Tld_Cursor
-- SET THE VARIABLE TO THE NEXT TLD
FETCH NEXT FROM Tld_Cursor INTO @TldExtension
-- LOOP
WHILE @@FETCH_STATUS = 0
BEGIN
-- IF FOUND RETURN 1
IF (CHARINDEX(@TldExtension, @Url) != 0) RETURN 1
-- ELSE GET NEXT
FETCH NEXT FROM Tld_Cursor INTO @TldExtension
END
-- IF NOT FOUND RETURN 0
RETURN 0
END
GO
原始文章已失效,a similar article 可能有用
答案 2 :(得分:0)
这是对不需要外部函数的函数的更新。另外,如果你想调试它,它也可以转换成一个程序。
DROP FUNCTION IF EXISTS IsValidURL
GO
CREATE FUNCTION [dbo].[IsValidUrl]
(
@Url varchar(100)
)
RETURNS BIT
AS
BEGIN
--PRINT('Original URL: '+@Url)
-- CLEAN THE URL
SET @Url = (SELECT REPLACE(@Url,'http://',''))
SET @Url = (SELECT REPLACE(@Url,'https://',''))
IF (CHARINDEX('/', @Url) !=0)
SET @Url = SUBSTRING(@Url, 0, CHARINDEX('/', @Url))
--PRINT('Cleaned URL: '+@Url)
IF (@Url LIKE '%[^a-zA-Z0-9.]%') -- check that the URL contains letters or the dot
BEGIN
RETURN 0;
--PRINT('0 -> Contains bad characters');
END
IF (CHARINDEX('.', @Url) = 0)
BEGIN
RETURN 0;
--PRINT('0 -> Doesn''t contain the dot character');
END
DECLARE @predot varchar(100)
DECLARE @postdot varchar(100)
WHILE ( CHARINDEX('.', @Url) != 0)
BEGIN
SET @predot = SUBSTRING(@Url, 0, CHARINDEX('.', @Url))
SET @postdot = SUBSTRING(@Url, CHARINDEX('.', @Url)+1, LEN(@Url))
--PRINT 'Pre dot: '+@predot
--PRINT 'Post dot: '+@postdot
IF (LEN(@predot) < 1)
BEGIN
RETURN 0;
--PRINT('0 -> Pre dot can''t be empty');
END
IF (LEN(@postdot) < 1)
BEGIN
RETURN 0;
--PRINT('0 -> Post dot can''t be empty');
END
SET @Url = @postdot
END
RETURN 1
--PRINT('1 -> Final return');
END
GO