从T-SQL中删除文本中的所有注释

时间:2017-11-02 18:38:30

标签: sql-server tsql

我正在尝试从NVARCHAR值中删除所有评论。

我不知道我将获得NVARCHAR变量的哪个值,我需要删除所有以#开头的注释 - 直到行尾。

例如:

-- Some Comments
SET NOCOUNT ON;

-- Some Comments

SELECT FirstName FROM dbo.Users WHERE Id = @Id;

删除评论后,它应如下所示:

SET NOCOUNT ON;



SELECT FirstName FROM dbo.Users WHERE Id = @Id;

在T-SQL中有没有简单的方法呢?

提前致谢。

1 个答案:

答案 0 :(得分:1)

使用ngramsN4k

unsigned char *image = SOIL_load_image ( "resources/images/sexy-girl.jpeg", &width, &height, &rchanel, 0 );

glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image );

SOIL_free_image_data ( image );

您可以使用以下解决方案解决此问题。这将仅限于CREATE FUNCTION dbo.NGramsN4K ( @string nvarchar(4000), -- Input string @N int -- requested token size ) /**************************************************************************************** Purpose: A character-level N-Grams function that outputs a contiguous stream of @N-sized tokens based on an input string (@string). Accepts strings up to 4000 nvarchar characters long. For more information about N-Grams see: http://en.wikipedia.org/wiki/N-gram. Compatibility: SQL Server 2008+, Azure SQL Database Syntax: --===== Autonomous SELECT position, token FROM dbo.NGramsN4K(@string,@N); --===== Against a table using APPLY SELECT s.SomeID, ng.position, ng.token FROM dbo.SomeTable s CROSS APPLY dbo.NGramsN4K(s.SomeValue,@N) ng; Parameters: @string = The input string to split into tokens. @N = The size of each token returned. Returns: Position = bigint; the position of the token in the input string token = nvarchar(4000); a @N-sized character-level N-Gram token Developer Notes: 1. NGramsN4K is not case sensitive 2. Many functions that use NGramsN4K will see a huge performance gain when the optimizer creates a parallel execution plan. One way to get a parallel query plan (if the optimizer does not chose one) is to use make_parallel by Adam Machanic which can be found here: sqlblog.com/blogs/adam_machanic/archive/2013/07/11/next-level-parallel-plan-porcing.aspx 3. When @N is less than 1 or greater than the datalength of the input string then no tokens (rows) are returned. If either @string or @N are NULL no rows are returned. This is a debatable topic but the thinking behind this decision is that: because you can't split 'xxx' into 4-grams, you can't split a NULL value into unigrams and you can't turn anything into NULL-grams, no rows should be returned. For people who would prefer that a NULL input forces the function to return a single NULL output you could add this code to the end of the function: UNION ALL SELECT 1, NULL WHERE NOT(@N > 0 AND @N <= DATALENGTH(@string)) OR (@N IS NULL OR @string IS NULL); 4. NGramsN4K is deterministic. For more about deterministic functions see: https://msdn.microsoft.com/en-us/library/ms178091.aspx Usage Examples: --===== Turn the string, 'abcd' into unigrams, bigrams and trigrams SELECT position, token FROM dbo.NGramsN4K('abcd',1); -- unigrams (@N=1) SELECT position, token FROM dbo.NGramsN4K('abcd',2); -- bigrams (@N=2) SELECT position, token FROM dbo.NGramsN4K('abcd',3); -- trigrams (@N=3) --===== How many times the substring "AB" appears in each record DECLARE @table TABLE(stringID int identity primary key, string nvarchar(100)); INSERT @table(string) VALUES ('AB123AB'),('123ABABAB'),('!AB!AB!'),('AB-AB-AB-AB-AB'); SELECT string, occurances = COUNT(*) FROM @table t CROSS APPLY dbo.NGramsN4K(t.string,2) ng WHERE ng.token = 'AB' GROUP BY string; ---------------------------------------------------------------------------------------- Revision History: Rev 00 - 20170324 - Initial Development - Alan Burstein ****************************************************************************************/ RETURNS TABLE WITH SCHEMABINDING AS RETURN WITH L1(N) AS ( SELECT 1 FROM (VALUES -- 64 dummy values to CROSS join for 4096 rows ($),($),($),($),($),($),($),($),($),($),($),($),($),($),($),($), ($),($),($),($),($),($),($),($),($),($),($),($),($),($),($),($), ($),($),($),($),($),($),($),($),($),($),($),($),($),($),($),($), ($),($),($),($),($),($),($),($),($),($),($),($),($),($),($),($)) t(N) ), iTally(N) AS ( SELECT TOP (ABS(CONVERT(BIGINT,((DATALENGTH(ISNULL(@string,''))/2)-(ISNULL(@N,1)-1)),0))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -- Order by a constant to avoid a sort FROM L1 a CROSS JOIN L1 b -- cartesian product for 4096 rows (16^2) ) SELECT position = N, -- position of the token in the string(s) token = SUBSTRING(@string,CAST(N AS int),@N) -- the @N-Sized token FROM iTally WHERE @N > 0 -- Protection against bad parameter values AND @N <= (ABS(CONVERT(BIGINT,((DATALENGTH(ISNULL(@string,''))/2)-(ISNULL(@N,1)-1)),0))); ,但如果您需要,我可以将NVARCHAR(4000)版本放在一起。另请注意,我的解决方案忽略以&#34; - &#34;开头的行。把一切都抓到了#34; - &#34;评论更深入的地方。我不是要NVARCHAR(max),而是可以修改这样做。

<强>解决方案

/* this comment style */

<强>前

-- sample stored proc
declare @storedproc varchar(8000) =
'-- Some Comments
SET NOCOUNT ON;

-- Some Comments

SELECT FirstName -- we only need the first name
FROM dbo.Users WHERE Id = @Id;';

--select @storedproc;

-- Solution
select cleanedProc = 
(
  select substring(item, 1, isnull(nullif(charindex('--', item),0)-1,nextPos))+br
  from
  (
    select 0 union all
    select position from dbo.ngramsN4k(@storedproc,1) 
    where token = char(10)
  ) d(position)
  cross apply (values (char(10), d.position+1,
           isnull(nullif(charindex(char(10), @storedproc, d.position+1),0),8000))
  ) p(br, startPos, nextPos)
  cross apply (values (substring(@storedproc, startPos, nextPos-startPos))) split(item)
  where item not like '--%'
  order by position
  for xml path(''), type
).value('(text())[1]', 'varchar(8000)');

<强>后

-- Some Comments
SET NOCOUNT ON;

-- Some Comments

SELECT FirstName -- we only need the first name
FROM dbo.Users WHERE Id = @Id;