2009-11-03 32 views
40

Dữ liệu của tôi trông giống nhưSQL Server thay thế, loại bỏ tất cả sau khi nhân vật nào đó

ID MyText 
1  some text; some more text 
2  text again; even more text 

Làm thế nào tôi có thể cập nhật MyText để thả tất cả mọi thứ sau dấu chấm phẩy và bao gồm cả ruột bán, vì vậy tôi là trái với những điều sau đây :

ID MyText 
1  some text 
2  text again 

Tôi đã xem SQL Server Replace, nhưng không thể nghĩ ra một cách khả thi để kiểm tra ";"

Trả lời

80

Sử dụng LEFT kết hợp với CHARINDEX:

UPDATE MyTable 
SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1) 
WHERE CHARINDEX(';', MyText) > 0 

Lưu ý rằng mệnh đề WHERE bỏ qua việc cập nhật hàng mà không có dấu chấm phẩy.

Dưới đây là một số mã để xác minh SQL trên công trình:

declare @MyTable table ([id] int primary key clustered, MyText varchar(100)) 
insert into @MyTable ([id], MyText) 
select 1, 'some text; some more text' 
union all select 2, 'text again; even more text' 
union all select 3, 'text without a semicolon' 
union all select 4, null -- test NULLs 
union all select 5, '' -- test empty string 
union all select 6, 'test 3 semicolons; second part; third part;' 
union all select 7, ';' -- test semicolon by itself  

UPDATE @MyTable 
SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1) 
WHERE CHARINDEX(';', MyText) > 0 

select * from @MyTable 

tôi nhận được kết quả như sau:

id MyText 
-- ------------------------- 
1 some text 
2 text again 
3 text without a semicolon 
4 NULL 
5  (empty string) 
6 test 3 semicolons 
7  (empty string) 
+1

Điều gì sẽ xảy ra nếu MyText không chứa ';' tính cách? Trong trường hợp đó, bạn sẽ không sử dụng âm 1 như tham số thứ hai trong left(). Trong trường hợp đó, trên hộp của tôi, tôi gặp lỗi "Tham số chiều dài không hợp lệ được chuyển đến hàm chuỗi con." – Mike

+0

@Mike Đó chính xác là vấn đề của tôi - Xem câu trả lời tiếp theo từ @najmeddine !! –

+1

Câu trả lời của @Mike Rashlien dưới đây giải quyết vấn đề này: TRÁI (MyText + ';', CHARINDEX (';', MyText + ';') - 1) – Tim

3

Sử dụng CHARINDEX để tìm ";". Sau đó, sử dụng SUBSTRING để chỉ trả lại phần trước ";".

2
UPDATE MyTable 
    SET MyText = SUBSTRING(MyText, 1, CHARINDEX(';', MyText) - 1) 
WHERE CHARINDEX(';', MyText) > 0 
+0

Chỉ cần cố gắng này, có vẻ như rời khỏi; cuối cùng. ;) – Jimmy

16

Đối với những lần khi một số lĩnh vực có một ";" và một số không bạn cũng có thể thêm một dấu chấm phẩy vào trường và sử dụng cùng một phương pháp được mô tả.

SET MyText = LEFT(MyText+';', CHARINDEX(';',MyText+';')-1) 
8

Có thể sử dụng CASE WHEN để những người không có ';' một mình.

SELECT 
    CASE WHEN CHARINDEX(';', MyText) > 0 THEN 
    LEFT(MyText, CHARINDEX(';', MyText)-1) ELSE 
    MyText END 
    FROM MyTable 
1

Đối với các trường hợp khi cần thay thế hoặc khớp (tìm) điều gì đó chống lại chuỗi, tôi thích sử dụng cụm từ thông dụng hơn.

Vì cụm từ thông dụng không được hỗ trợ đầy đủ trong T-SQL, bạn có thể triển khai chúng bằng cách sử dụng các chức năng CLR. Hơn nữa, bạn không cần bất kỳ kiến ​​thức nào C# hoặc CLR vì tất cả những gì bạn cần đã có sẵn trong MSDN String Utility Functions Sample.

Trong trường hợp của bạn, giải pháp sử dụng biểu thức thông thường là:

SELECT [dbo].[RegexReplace] ([MyColumn], '(;.*)', '') 
FROM [dbo].[MyTable] 

Nhưng thực hiện chức năng này trong cơ sở dữ liệu của bạn sẽ giúp bạn giải quyết các vấn đề phức tạp hơn chút nào.


Ví dụ dưới đây cho thấy làm thế nào để triển khai chỉ [dbo].[RegexReplace] chức năng, nhưng tôi sẽ giới thiệu cho bạn triển khai cả lớp String Utility.

  1. Bật hội nhập CLR. Thực hiện các lệnh Transact-SQL sau đây:

    sp_configure 'clr enabled', 1 
    GO 
    RECONFIGURE 
    GO 
    
  2. Viết mã (hoặc tạo .dll). Generraly, bạn có thể làm điều này bằng cách sử dụng Visual Studio hoặc.NET Framework nhắc lệnh (như nó được hiển thị trong bài viết), nhưng tôi thích sử dụng studio trực quan.

    • tạo dự án thư viện lớp mới:

      enter image description here

    • sao chép và dán đoạn mã sau vào file Class1.cs:

      using System; 
      using System.IO; 
      using System.Data.SqlTypes; 
      using System.Text.RegularExpressions; 
      using Microsoft.SqlServer.Server; 
      
      public sealed class RegularExpression 
      { 
          public static string Replace(SqlString sqlInput, SqlString sqlPattern, SqlString sqlReplacement) 
          { 
           string input = (sqlInput.IsNull) ? string.Empty : sqlInput.Value; 
           string pattern = (sqlPattern.IsNull) ? string.Empty : sqlPattern.Value; 
           string replacement = (sqlReplacement.IsNull) ? string.Empty : sqlReplacement.Value; 
           return Regex.Replace(input, pattern, replacement); 
          } 
      } 
      
    • xây dựng các giải pháp và nhận được đường dẫn đến tệp được tạo ra .dll:

      enter image description here

    • thay thế đường dẫn đến tập tin .dll trong T-SQL câu sau đây và thực hiện chúng:

      IF OBJECT_ID(N'RegexReplace', N'FS') is not null 
      DROP Function RegexReplace; 
      GO 
      
      IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'StringUtils') 
      DROP ASSEMBLY StringUtils; 
      GO 
      
      DECLARE @SamplePath nvarchar(1024) 
      -- You will need to modify the value of the this variable if you have installed the sample someplace other than the default location. 
      Set @SamplePath = 'C:\Users\gotqn\Desktop\StringUtils\StringUtils\StringUtils\bin\Debug\' 
      CREATE ASSEMBLY [StringUtils] 
      FROM @SamplePath + 'StringUtils.dll' 
      WITH permission_set = Safe; 
      GO 
      
      
      CREATE FUNCTION [RegexReplace] (@input nvarchar(max), @pattern nvarchar(max), @replacement nvarchar(max)) 
      RETURNS nvarchar(max) 
      AS EXTERNAL NAME [StringUtils].[RegularExpression].[Replace] 
      GO 
      
    • Vậy là xong. Kiểm tra chức năng của bạn:

      declare @MyTable table ([id] int primary key clustered, MyText varchar(100)) 
      insert into @MyTable ([id], MyText) 
      select 1, 'some text; some more text' 
      union all select 2, 'text again; even more text' 
      union all select 3, 'text without a semicolon' 
      union all select 4, null -- test NULLs 
      union all select 5, '' -- test empty string 
      union all select 6, 'test 3 semicolons; second part; third part' 
      union all select 7, ';' -- test semicolon by itself  
      
      SELECT [dbo].[RegexReplace] ([MyText], '(;.*)', '') 
      FROM @MyTable 
      
      select * from @MyTable 
      
Các vấn đề liên quan