Преобразованная функция из С# в vb.net работает неправильно

avatar
Ted Kon
8 августа 2021 в 23:27
65
1
-1

У меня есть этот код C#, который может преобразовывать динамический запрос sql в простой запрос sql

    using System;
    using System.Linq;
    using System.Text.RegularExpressions;
                        
    public class Program
    {
        public static void Main()
        {
            var sql = @"
exec sp_executesql N' select Blobdata from ES00Blob  where KeyID = @KeyID AND ObjectID = @ObjectID  ',N'@KeyID nvarchar(15),@ObjectID nvarchar(13),@TypeID int',@KeyID=N'100',@ObjectID=N'ES00DBPROFILE'
    ";
            Console.WriteLine(ConvertSql(sql));
        }
    
        public static string ConvertSql(string origSql)
        {
            var re = new Regex(@"exec*\s*sp_executesql\s+N'([\s\S]*)',\s*N'(@[\s\S]*?)',\s*([\s\S]*)", RegexOptions.IgnoreCase); // 1: the sql, 2: the declare, 3: the setting
            var match = re.Match(origSql);
            if (match.Success)
            {
                var sql = match.Groups[1].Value.Replace("''", "'");
                var setting = match.Groups[3].Value + ',';
        
                var re2 = new Regex(@"@[^',]*?\s*=");
                var variables = re2.Matches(setting).Cast<Match>().Select(m => m.Value).ToArray();
                var values = re2.Split(setting).Where(s=>!string.IsNullOrWhiteSpace(s)).Select(m => m.Trim(',').Trim().Trim(';')).ToArray();
                for (int i = variables.Length-1; i>=0; i--)
                {
                    sql = Regex.Replace(sql, "(" + variables[i].Replace("=", "")+")", values[i], RegexOptions.Singleline | RegexOptions.IgnoreCase);
                }
                return sql;
            }
        
            return @"Unknown sql query format.";
    
        }
    }

Например, его результат для запроса в переменной sql выглядит следующим образом:

select Blobdata from ES00Blob  where KeyID = N'100' AND ObjectID = N'ES00DBPROFILE'

Когда я конвертирую его в vb.net через этот сайт https://converter.telerik.com, чтобы использовать его в проекте vb.net, он преобразуется, как показано ниже

     Imports System
        Imports System.Linq
        Imports System.Text.RegularExpressions
        
        Public Class Program
            Public Shared Sub Main()
                Dim sql = "

exec sp_executesql N' select Blobdata from ES00Blob  where KeyID = @KeyID AND ObjectID = @ObjectID  ',N'@KeyID nvarchar(15),@ObjectID nvarchar(13),@TypeID int',@KeyID=N'100',@ObjectID=N'ES00DBPROFILE'
        
        "
                Console.WriteLine(ConvertSql(sql))
            End Sub
        
            Public Shared Function ConvertSql(ByVal origSql As String) As String
                Dim re = New Regex("exec*\s*sp_executesql\s+N'([\s\S]*)',\s*N'(@[\s\S]*?)',\s*([\s\S]*)", RegexOptions.IgnoreCase)
                Dim match = re.Match(origSql)
        
                If match.Success Then
                    Dim sql = match.Groups(1).Value.Replace("''", "'")
                    Dim setting = match.Groups(3).Value & ","c
                    Dim re2 = New Regex("@[^',]*?\s*=")
                    Dim variables = re2.Matches(setting).Cast(Of Match)().[Select](Function(m) m.Value).ToArray()
                    Dim values = re2.Split(setting).Where(Function(s) Not String.IsNullOrWhiteSpace(s)).[Select](Function(m) m.Trim(","c).Trim().Trim(";"c)).ToArray()
        
                    For i As Integer = variables.Length - 1 To 0
                        sql = Regex.Replace(sql, "(" & variables(i).Replace("=", "") & ")", values(i), RegexOptions.Singleline Or RegexOptions.IgnoreCase)
                    Next
        
                    Return sql
                End If
        
                Return "Unknown sql query format."
            End Function
        End Class

но несмотря на то, что он работает, он не заменяет динамические значения.

Он возвращает это

выберите Blobdata из ES00Blob, где KeyID = @KeyID AND ObjectID = @ObjectID

Я заметил, что при преобразовании отсутствует символ @ перед кавычками переменной sql и в команде возврата функции. В vb.net я не могу использовать символ @.

Есть идеи, что может быть не так в преобразовании?

Источник
Caius Jard
8 августа 2021 в 23:42
2

Попробуйте другой конвертер; наверное быстрее, чем прорабатывать и исправлять себя. Мне нравится icsharpcode — codeconverter.icsharpcode.net

Anu6is
8 августа 2021 в 23:45
0

ваша переменная sql не является одной и той же строкой в ​​С# и vb. Версия vb не возвращает совпадений с регулярными выражениями. Вы можете проверить это в онлайн-инструменте регулярных выражений.

Ted Kon
8 августа 2021 в 23:49
0

@Anu6is, это была ошибка копирования в первые минуты поста. Я тут же исправил. Строка одинаковая в обоих.

Ted Kon
9 августа 2021 в 00:04
0

@CaiusJard Большое спасибо! Моя проблема была решена только с помощью предложенного вами конвертера (codeconverter.icsharpcode.net)!!!

Hursey
9 августа 2021 в 00:08
4

Зачем вообще конвертировать? Почему бы не сослаться на C#dll из проекта vb.net?

jmcilhinney
9 августа 2021 в 00:14
1

Я предлагаю вообще не использовать онлайн-конвертеры. Некоторые лучше, чем другие, но у всех есть проблемы. Я рекомендую загрузить Instant VB от Tangible Software Solutions. Бесплатной версии достаточно для большинства людей, и она постоянно обновляется для поддержки новых языковых функций.

Ответы (1)

avatar
user9938
9 августа 2021 в 03:25
0

В цикле For отсутствует Step -1.

Изменить:

For i As Integer = variables.Length - 1 To 0

Кому:

For i As Integer = variables.Length - 1 To 0 Step -1

ConvertSql:

Public Shared Function ConvertSql(ByVal origSql As String) As String
    Dim re = New Regex("exec*\s*sp_executesql\s+N'([\s\S]*)',\s*N'(@[\s\S]*?)',\s*([\s\S]*)", RegexOptions.IgnoreCase)
    Dim match = re.Match(origSql)

    If match.Success Then
        Dim sql = match.Groups(1).Value.Replace("''", "'")
        Dim setting = match.Groups(3).Value & ","c
        Dim re2 = New Regex("@[^',]*?\s*=")
        Dim variables = re2.Matches(setting).Cast(Of Match)().[Select](Function(m) m.Value).ToArray()

        Dim values = re2.Split(setting).Where(Function(s) Not String.IsNullOrWhiteSpace(s)).[Select](Function(m) m.Trim(","c).Trim().Trim(";"c)).ToArray()

        For i As Integer = variables.Length - 1 To 0 Step -1
            sql = Regex.Replace(sql, "(" & variables(i).Replace("=", "") & ")", values(i), (RegexOptions.Singleline Or RegexOptions.IgnoreCase))
        Next

        Return sql
    End If

    Return "Unknown sql query format."
End Function