2016-06-30 2 views
-1

現在、ストアドプロシージャで生成されたバグのある動的クエリがあります。どういうわけか、そこには連続した重複「AND」が生成されています。SQL Server:文字列内の連続する重複する単語を削除する方法

動的問合せ文字列から連続問合せ 'AND'を削除する方法があるかどうかを知ることができます。例えばのために

var str = 'Select * from employee A where A.age > 30 AND AND A.role = ''developer''' 

更新

doesntの仕事 の下に示唆されているように置き換える以下のクエリを参照してください。

DECLARE 
     @str NVARCHAR(MAX) 



     SET @str = 'fasdf asdfasf asfasdfasafsdf AND  AND  asdfasdfasd AND dfasdfa' 


    SET @str = REPLACE(@str, 'AND AND', 'AND') 

    PRINT @str 

ありがとう!

+3

間違った結果の上に修正を「パッチする」のではなく、**実際のバグ**(コアの問題)を修正してください! –

+1

このクエリの生成方法。?? – Wanderer

+0

@ Mark_sに同意しますが、パッチを追加することで問題を管理するのは正しくありません。動的SQLが作成される場所を確認してください。 http://www.kodyaz.com/articles/build-sql-server-dynamic-sql-query-example.aspx動的SQL問合せがビルドされ、「WHERE」句と「AND」句が注意深く処理される場所を確認できます。 – Eralper

答えて

2

何か?

/****** Object: StoredProcedure [dbo].[RemoveConsecutiveDuplicateTokens] Script Date: 30/06/2016 09:30:50 ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE procedure [dbo].[RemoveConsecutiveDuplicateTokens] 
@instr varchar(max) , 
@outstr varchar(max) OUTPUT 
as 
declare @workstr varchar(max) = ltrim(@instr), 
     @newstr varchar(max), 
     @oldtoken varchar(max), 
     @newtoken varchar(max) 

while @workstr is not null 
begin 
    if @oldtoken is null 
     begin 
     set @oldtoken = SUBSTRING(@workstr,1,charindex(' ',@workstr)) 
     set @workstr = ltrim(Stuff(@workstr, CharIndex(@oldtoken,@workstr), Len(@oldtoken), '')) 
     set @newstr = @oldtoken + ' ' 
     end 
    set @newtoken = SUBSTRING(@workstr,1,charindex(' ',@workstr)) 

    if @newtoken <> @oldtoken 
     begin 
      if @newtoken <> char(39) 
       begin 
        set @oldtoken = @newtoken 
        set @newstr = @newstr + @newtoken + ' ' 
        set @workstr = ltrim(Stuff(@workstr, CharIndex(@newtoken,@workstr), Len(@newtoken), '')) 
       end 
     end 
    else 
     begin 
      set @workstr = ltrim(Stuff(@workstr, CharIndex(@newtoken,@workstr), Len(@newtoken), '')) 
     end 

    if charindex(' ',@workstr) = 0 
     break 
end 
set @newtoken = SUBSTRING(@workstr,1,len(@workstr)) 
    if @newtoken <> @oldtoken 
     begin 
      if @newtoken <> char(39) 
       begin 
        set @oldtoken = @newtoken 
        set @newstr = @newstr + @newtoken + ' ' 
        set @workstr = ltrim(Stuff(@workstr, CharIndex(@newtoken,@workstr), Len(@newtoken), '')) 
       end 
     end 
    else 
     begin 
      set @workstr = ltrim(Stuff(@workstr, CharIndex(@newtoken,@workstr), Len(@newtoken), '')) 
     end 
select @outstr = @newstr 

return 
+0

うん、ちょうど仕事、ありがとう! –

+0

+1私は似たようなことをやろうとしていましたが、あなたの答えはかなり完成しています。それは、意図的な重複がない限り、SP文字列全体を解決します...あなたのコードでは、それほど簡単に修正することはできますが。 –

1

まず、あなたは間違っています。この不正なSQLを生成するロジックを修正します。

しかし、研究/学習目的では、これはあなたのやり方です。

REPLACE (str , 'AND AND' , 'AND') 
+0

私はその間違いを知っていて、他には何も動作しない場合にのみ使用されます...しかし、スペースの数、2 'AND'つまり余分な空白や新しい行がある可能性があるので、上記の作業はすぐにはできません –

+0

Darkknightなどの提案と同様に、エラーの原因を見つけて修正しましたが、このポストのためにこれを答えとして選んでください。他の人も正しいですが、この答えは最短の解決策です。 –

+0

残念ながら、この解決策は機能しません。 @clifton_h私はあなたが言ったように余分なスペースをSQL Serverが無視すると思いません。更新された投稿の例を見てください –

0

は、REPLACE機能を使用して、 'AND AND'を 'AND'で置き換えます。例

SELECT REPLACE('Select * from employee A where A.age > 30 AND AND A.role = ''developer'' ','AND AND','AND'); 
1

は私がSUBSTRINGを嫌いどのくらい忘れてしまったが、その後として真に価値で始まる位置を<starting_position>を読むために、私の闘争されていること。

しかし、実際の獣は、@@TRANCOUNTのコンテキストでSQL Serverで文字列操作をどのように実装するかということでした。

  • 文を考えてみましょう

    PRINT QUOTE_NAME(REPLACE('My____Table', '__', '_'))

我々は適切な命名規則を使用したいが、関数は返します

`[My__Table]` 

はなぜ? REPLACEは重複の長さを先にジャンプするためです。それを証明するために、CHAR(95)「_」1以上を追加することができますし、私たちはお返しにこれを取得する:

`[My___Table]` 

それでは単にWHILE文でこれを埋め込む、例えば、我々のニーズのために非常に十分であろう。 注私は読みやすくするために '_' とスペースを置き換える

DECLARE @instr varchar(max) 
    SET @instr = 'SELECT * from employee A where A.age > 30 AND AND A.role = ''developer''' 

    DECLARE @workstr varchar(max) = REPLACE(LTRIM(@instr), ' ', '_'), 
    @tokenque VARCHAR(MAX), 
    @newstr INT = 0, 
    @token varchar(max), 
    @flag_break INT = 0 

-- removes the extra "spaces" 
    WHILE CHARINDEX('__', @workstr) <> 0 
     BEGIN 
     SET @workstr = REPLACE(@workstr, '__' , '_') 
     END 
    SET @tokenque = @workstr 
    WHILE (CHARINDEX('_', @tokenque) <> 0) 
    BEGIN 
    SET @token = SUBSTRING(@tokenque, 1, CHARINDEX('_', @Tokenque) - 1) 
    IF @token <> '''' -- (') delimiter skipped 
     BEGIN 
     WHILE CHARINDEX(@token + '_' + @token, @workstr) <> 0 
     BEGIN 
     SET @workstr = REPLACE(@workstr, @token + '_' + @token, @token) 
     END 
     SET @tokenque = SUBSTRING(@tokenque, LEN(@token) + 2, LEN(@tokenque)) 
     END 
    ELSE SET @tokenque = SUBSTRING(@tokenque, LEN(@token) + 2, LEN(@tokenque)) 

    PRINT @tokenque --if you want to see the progression 
    END 
PRINT REPLACE(@workstr, '_', ' ') 

結果:このような

'SELECT * from employee A where A.age > 30 AND A.role = 'developer' 
+0

これは本当に従うのは簡単でした、私は言う必要があります、それを分解する良い仕事! –

+0

@ Mr.Kありがとうございます。最終的に 'CHARINDEX'と' SUBSTRING'を正しく理解していると思います。だから私が学ぶのを助けてくれてありがとう:) –

関連する問題