In vb.net, I need to split a string multiple ways to create a list of commands

StackOverflow https://stackoverflow.com/questions/23641739

  •  22-07-2023
  •  | 
  •  

Pergunta

Lets say I have a string that contains stored procedure names, their parameters, and values, like this:

Dim sprocs As String = "Procedure: NameOfProcedure, Parameters: @Param1(int), @Param2(varchar) Values: Something, SomethingElse ; Procedure: NameOfProcedure, Parameters: @Param1(int), @Param2(varchar) Values: Something, Something Else"

My point of the above is I need to be able to take a user defined string that can store multiple procedures separated by... something. In this case I used a ; semicolon.

What I need to be able to do is a FOR EACH on these in vb.net.

I know how to used stored procedures and set parameters... I'm just not sure of the best way to go about this as far as how to split up that string to match parameters and values, etc.

So a bad example:

Dim ConnectionString As String = "String...removed"
    Dim conn As New System.Data.SqlClient.SqlConnection(ConnectionString)

    ' So I need a for each here
    Dim cmd As New System.Data.SqlClient.SqlCommand(ProcedureName)
    With cmd
        .Connection = conn
        .CommandType = CommandType.StoredProcedure
        ' and a for each here on the parameters, datatypes, and their values          
        .Parameters.Add(ParamName, DataType).Value = TheValue
        .Connection.Open()
        .BeginExecuteReader()
        .Connection.Close()
    End With

So the splitting and parsing out the string is my biggest roadblock on this. I'm not sure how to separate it out at this level, match parameters, datatypes and their values all together. If there's a better way to have the end-user organize the string to make parsing and splitting easier, please share.

Any suggestions or examples are greatly appreciated.

Thank you very much.

Foi útil?

Solução

There's a temptation here to use String.Split() or a regular expression. Neither solution is actually very good for this. To understand what I mean, take a quick moment to search Google for the many thousands of posts of programmers working with CSV running into edge cases where their regex didn't quite cut it. For this purpose, your semi-colon delimiter is not significantly different than a fancy comma.

Depending on the regex engine, it may actually be possible to build an expression that does this, especially if you can put certain constraints on the data. However, such expressions tend to be very tough to build and maintain, and they tend to require backtracking, which hurts performance.

The next alternative to examine is a dedicated parser. For CSV data, this is the panacea. There a number of good ones available for most any platform that you can just plug in, and they're typically pretty easy to work with. However, what you have, while similar, goes a bit beyond the level of what these parsers are written to handle.

One related solution is write your own csv-like parser. This may be your best option, and if you choose this route all I can do is recommend that you build a state machine to go character by character through the input string.

The next rung up the ladder is to use a generic parser/interpretter that relies on something like ANTLR. I'm haven't personally dug very deep into that well, but I know the tools are out there.

One related option, that I think is probably your best option here overall, is a Domain Specific Language (DSL). This is something that may be a little easier to get started with than a tool like ANTLR, especially because it's already built into Visual Studio. However, this option requires that you be able to control your input format.

If all this sounds like more work than it should be, you're right. The good news is that is possible to skip all this. The trick is that you must first impose artificial constraints on your data. For example, a constraint that parameter values are not allowed to contain ; characters means you can get back to a String.Split() solution to divide out each separate procedure call. Now your function is no longer generally applicable, but then maybe is doesn't need to be. When you create these constraints, make sure they are documented, so that when something violates them and code explodes you'll have clear definitions for why.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top