SQL中的字符串函数而不是C#

时间:2016-11-18 17:04:07

标签: c# sql sql-server sql-server-2008

我有2000000个拥有客户名称的sql记录。我想改变如下。

示例数据:

Name
अमरीनaa मोयोद्दिनa शेखa
रऊफa वाहेदaa शेखa 
शहेदाबेगमaa रऊफaa शेखa
इम्रानa रउफ़aa शेखa 
दत्तुaa
कैलास धुमाळ
विलास दत्तु धुमाळ 
बिस्मिल्ला बी अ.हमीद खॉन
इस्माईल खॉन अ.हमीद खॉन 
नसरीन बेगम इस्माईल खान 
अ.हमिद खॉन इमाम खॉन
अजमेर खॉ इमाम खॉ
सुग्रा बी अजमेर खॉ
हनीफाबी अजमेर 
गौस अजमेर खान 
यासीन अजमेर खान 
राबिया बी मुश्ताक अली शेख
मो.सिंकंदर अली अन्वरअली शेख 
गफार मोयीन शेख 
नंदाबाई अशोक 
सचिन आशोक दिवेकर
सोनाजी नामदेव बोराडे
व्दारका राजू गायकवाड 
लिलाबाई सोनाजी बोराडे 
शारदाबाई राजू जगदाळे
अनिता अर्जुन जगदाळे
मंदा सुनील वाढेकर 
विठ्ठल दगडू 
सुनिल विश्वनाथ वाढेकर
शिवाजी विश्वनाथ
गयाबाई शिवाजी 
बाळू विश्वनाथ
वैशाली बाळू वाढेकर 
पांडुरंग नामदेब वाघ नामदेव 
हिराबाई पांडुरंग बाघ पांडुरंग 
सवीता संतोष किर्तीकर
चंद्रकला प्रल्हाद
संतोष प्रल्हाद
अनिल प्रल्हाद
विजय प्रल्हाद किर्तीकर 
राजेंद्र काशिनाथ 
हिराबाई राजेंद्र 
सुरेश पैठणे
नुतन सुरेश 
गौतम पैठणे
शारदा गौतम पैठणे गौतम
राजू अंबादास 
शोभाबाई राजू
सुनिता गोटीराम गायकवाड
बाळकृष्ण भानुदास दुलग

上面的数据包含名字,姓名,姓名,我希望:

  1. 在名字的每个单词中,aa应该替换为单个a,这是任何名字的地方(अमरीनaa将是अमरीन和रऊफaa将是ऊ)
  2. 在名字的每个单词中,a应该被删除,这是最后的单词(शेखa将是शेख和मोयोद्दिनa将是मोयोद्दिन)
  3. 如果名字有超过2个单词,那么最后一个单词将在fisrt中(विलासदत्तुधुमाळ将是धुमाळविलासदत्तु)
  4. 如果名字少于3个字,那么它将是相同的,如果它是कैलासधुमाळ将कैलासधुमाळ和दत्तुaa将是दत्तुaa)
  5. 应删除所有盯着和结束空格的单词。
  6. 对于Above要求我使用C#硬代码来完全填充但是需要5到8个小时来完成,我希望这应该在sql端完成。

    这里是我的C#代码:

     int _pcount = 0;
    string _qr = "";
    string _Name = "";
    string _FinalName = "";
    string _FNAME = "";
    string _LastName = "";
    string _MiddleName = "";
    string _ID = "";
    string[] _Split;
    List<string> _a = new List<string>();
    DataRowCollection _dr = _CDatabase._MGetDataRows("SELECT _ID, _FULLNAME FROM MYTABLE ORDER BY _FULLNAME"); // This is a function will execute a sql and return DataRowCollection
    progressBar1.Maximum = _dr.Count + 1;
    progressBar1.Value = 0;
    using (SqlConnection con = new SqlConnection("MyConStr"))
    {
        con.Open();
        using (SqlTransaction trans = con.BeginTransaction(IsolationLevel.ReadCommitted))
        {
            try
            {
                foreach (DataRow _row in _dr)
                {
                    progressBar1.Value++;
                    _pcount++;
                    if (_pcount >= 100)
                    {
                        _pcount = 0;
                        Application.DoEvents();
                    }
                    _ID = _CConvert._MConvertToString(_row[0]);
                    _Name = _CConvert._MConvertToString(_row[1]);
    
                    _Split = _Name.Split(' ');
                    _a = _Split.ToList();
                    _a.Remove(" ");
                    _a.Remove(" ");
                    _a.Remove(" ");
                    _a.Remove(" ");
                    _a.Remove(" ");
                    _a.Remove(" ");
                    switch (_a.Count)
                    {
                        case 0:
                            {
                                _FNAME = _FinalName = _Name;
                                _FNAME = _Name;
                                _LastName = "";
                                _MiddleName = "";
                                break;
                            }
                        case 1:
                            {
                                _FNAME = _FinalName = _Name;
                                _FNAME = "";
                                _LastName = _Name;
                                _MiddleName = "";
                                break;
                            }
                        case 2:
                            {
                                _FNAME = _FinalName = _Name;
                                _FNAME = _a[0];
                                _LastName = _FNAME;
                                _MiddleName = _a[1];
                                break;
                            }
    
                        case 3:
                            {
                                _FinalName = _a[2] + " " + _a[0] + " " + _a[1];
                                _FNAME = _a[0];
                                _MiddleName = _a[1];
                                _LastName = _a[2];
                                break;
                            }
                        case 4:
                            { // nasreen begum ismail khan
                                _FinalName = _a[3] + " " + _a[0] + " " + _a[1] + " " + _a[2];
                                _FNAME = _a[0] + " " + _a[1]; // nasreen begum
                                _MiddleName = _a[2];// ismail
                                _LastName = _a[3];//khan
                                break;
                            }
    
                        case 5:
                            { // jaibunnisa begum gulam dastagir sahab syed
                                _FinalName = _a[4] + " " + _a[0] + " " + _a[1] + " " + _a[2] + " " + _a[3];
                                _FNAME = _a[0] + " " + _a[1]; // jaibunnisa begum
                                _MiddleName = _a[2] + " " + _a[3];// gulam gastagir
                                _LastName = _a[4];//syed
                                break;
                            }
    
                        case 6:
                            { // jaibunnisa begum gulam dastagir syed
                                _FinalName = _a[5] + " " + _a[0] + " " + _a[1] + " " + _a[2] + " " + _a[3] + " " + _a[4];
                                _FNAME = _a[0] + " " + _a[1]; // jaibunnisa begum
                                _MiddleName = _a[2] + " " + _a[3] + " " + _a[4];// gulam gastagir
                                _LastName = _a[5];//syed
                                break;
                            }
                        case 7:
                            { // jaibunnisa begum gulam dastagir syed
                                _FinalName = _a[6] + " " + _a[0] + " " + _a[1] + " " + _a[2] + " " + _a[3] + " " + _a[4] + " " + _a[5];
                                _FNAME = _a[0] + " " + _a[1]; // jaibunnisa begum
                                _MiddleName = _a[2] + " " + _a[3] + " " + _a[4] + " " + _a[5];// gulam gastagir
                                _LastName = _a[6];//syed
                                break;
                            }
                        default:
                            {
                                _FinalName = _Name;
                                _FNAME = "";
                                _LastName = "";
                                _MiddleName = "";
                                break;
                            }
                    }
    
                    _qr = "UPDATE MYTABLE SET _FULLNAME = N'" + _FinalName + "' WHERE _ID = '" + _ID + "'";
                    _mExcute(_qr, con, trans);
                }
                trans.Commit();
                con.Close();
                trans.Dispose();
                MessageBox.Show("DONE");
            }
            catch (Exception ex)
            {
                trans.Rollback();
                con.Close();
                _CShowMessageBox._MShowErrorMessageBox(ex.Message);
            }
        }
    }
    

3 个答案:

答案 0 :(得分:3)

我不清楚你的字符串处理是否可以在SQL中轻松实现,但为了更快,它必须允许基于集合的方法。类似的东西:

UPDATE MYTABLE SET _FULLNAME = dbo.getFullName(paramters)

代码缓慢的主要原因是UPDATE语句数量巨大。如果使用SQL事件探查器,您将看到生成了多少活动。

在尝试转换为SQL之前,我会尝试以下操作:

1)将您的全名预先计算到字符串列表中 2)创建一个缓冲表,其结构如下(缓冲区):

ID INT NOT NULL,
FullName NVARCHAR(255) NOT NULL

3)使用Bulk Insert持久保存到缓冲区。 Bulk insert速度要快得多(几十次,如果不是几次加速),因为它最大限度地减少了应用程序和SQL Server之间的往返行程。

4)使用语句从缓冲区更新到最终表格

UPDATE Dest
SET T.FullName = B.FullName
FROM MYTABLE T
JOIN Buffer B ON B.ID = T.ID

答案 1 :(得分:2)

首先创建两个函数:

-- Splits the name parts
CREATE FUNCTION [dbo].[Split]
(
    @String NVARCHAR(4000),
    @Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
    WITH Split(stpos,endpos)
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
            FROM Split
            WHERE endpos > 0
    )
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
    FROM Split
)

-- Formats the name
CREATE FUNCTION [dbo].[FormatName]
( 
    @Name NVARCHAR(200)
)
RETURNS NVARCHAR(200)
AS
BEGIN
    DECLARE @CountNameParts AS INT
    DECLARE @FirstName AS NVARCHAR(200)
    DECLARE @MiddleName AS NVARCHAR(200)
    DECLARE @LastName AS NVARCHAR(200)

    SET @CountNameParts = 0
    SET @FirstName = ''
    SET @MiddleName = ''
    SET @LastName = ''

    DECLARE @UserName TABLE(
        Id INT NOT NULL,
        DATA NVARCHAR(200) NOT NULL
    )

    --5.All Words staring and ending blank spaces should be removed.
    INSERT INTO @UserName
    SELECT ID, Data
    from dbo.Split(LTRIM(RTRIM(@Name)), ' ')

    SELECT @CountNameParts=count(*) from @UserName
    IF @CountNameParts = 3
    BEGIN
        SELECT @LastName=Data from @UserName where Id = 3
        SELECT @MiddleName=Data from @UserName where Id = 2
        SELECT @FirstName=Data from @UserName where Id = 1
    END
    ELSE IF @CountNameParts = 2
    BEGIN
        SELECT @LastName=Data from @UserName where Id = 2
        SELECT @FirstName=Data from @UserName where Id = 1
    END
    ELSE
    BEGIN
        SELECT @FirstName=Data from @UserName where Id = 1
    END

    --2.In every words of names a should be removed which is in in last in word ( शेखa will be शेख and मोयोद्दिनa will be मोयोद्दिन)
    SELECT @LastName=REPLACE(@LastName, 'a', '')

    --1.In every words of names aa should be replace with single a which is any where in name ( अमरीनaa will be अमरीन and रऊफaa will be रऊफ)
    SELECT @FirstName=REPLACE(@FirstName, 'aa', 'a')
    SELECT @MiddleName=REPLACE(@MiddleName, 'aa', 'a')
    SELECT @LastName=REPLACE(@LastName, 'aa', 'a')

    --3.If names have more then 2 words then last word will be in fisrt (विलास दत्तु धुमाळ will be धुमाळ विलास दत्तु)
    IF @CountNameParts = 2
    BEGIN
        SET @MiddleName=@FirstName
        SET @FirstName=@LastName
        SET @LastName=@MiddleName
        SET @MiddleName=''
    END

    --4.If names have less then 3 words then it will be same as it is कैलास धुमाळ will कैलास धुमाळ and दत्तुaa will be दत्तुaa)

    RETURN @FirstName + ' ' + @MiddleName + ' ' + @LastName
END

然后就像这样进行大规模的更新:

UPDATE MYTABLE SET _FULLNAME = [dbo].[FormatName](_FULLNAME)

答案 2 :(得分:0)

您可以使用C#语言编写SQL CLR函数。 您可以在一个更新中的SQL语句和comlete任务中使用此函数!

[SqlFunction()]
public static SqlDouble addTax(SqlDouble originalAmount)
{
    < here is your code in C# (you already done this part!)>
}

文章如何部署: http://www.c-sharpcorner.com/UploadFile/dacca2/sql-clr-for-beginner-part-3-create-function-in-sql-clr/