简体   繁体   English

创建插入语句-Windows应用程序Vb.Net

[英]Creating An Insert Statement — Windows application Vb.Net

I am doing windows appliction in vb.net. 我正在vb.net中执行Windows appliction。 i have customer object contains save method. 我有客户对象包含保存方法。 how do i generate insert query? 如何生成插入查询?

I need to save the object in relational database (SQL server). 我需要将对象保存在关系数据库(SQL Server)中。 I need to know which is the correct way of doing the insertion ie,. 我需要知道哪种是正确的插入方法,即。 Inside the save method i have written the SQL statement to save the object. 在save方法内部,我编写了SQL语句来保存对象。 Is it the correct way? 这是正确的方法吗?

Thanks 谢谢

A simple INSERT statement for SQL takes this basic form: 用于SQL的简单INSERT语句采用以下基本形式:

INSERT INTO [tablename] ( [column1], [column2], ... ) VALUES ( [value1], [value2], ...)

So, we obviously need to know about the database table you are using: what columns it has. 因此,我们显然需要了解您正在使用的数据库表:它具有哪些列。 We also need to know about the class: what properties it has. 我们还需要了解该类:它具有什么属性。 Finally, we need to know about the data types for the table columns and class properties, and how the properties will map to the columns. 最后,我们需要了解表列和类属性的数据类型,以及这些属性将如何映射到列。 For very simple objects the names and types will just line up. 对于非常简单的对象,名称和类型将对齐。 But in other cases your class may itself contain a collection (or several) that would mean inserting data into more than one table. 但是在其他情况下,您的类本身可能包含一个(或多个)集合,这意味着将数据插入多个表中。

After all this is determined, we still need two things: connection information for the database (usually distilled down into a single connection string ) and whether or not you are concerned that your class instance may have been saved previously, in which case you want to build an UPDATE statement rather than INSERT. 确定所有这些条件之后,我们仍然需要两件事:数据库的连接信息(通常精简为单个连接字符串 )以及您是否担心类实例可能以前已经保存过,在这种情况下,您要构建一个UPDATE语句而不是INSERT。

Assuming you can answer all of that in a satisfactory manner, your VB.Net code will look something like this (of course substituting your specific column, property, type, and connection information where appropriate): 假设您可以满意地回答所有问题,那么您的VB.Net代码将类似于以下内容(当然,在适当的地方替换您的特定列,属性,类型和连接信息):

Public Class Customer
    Public Sub Save()
        DAL.SaveCustomer(Me)
    End Sub

    '   ...'

End Class

.

' a VB Module is a C# static class'
Public Module DAL 
    Private ConnString As String = "Your connection string here"

    Public Sub SaveCustomer(ByVal TheCustomer As Customer)
        Dim sql As String = "" & _
        "INSERT INTO [MyTable] (" & _
            "[column1], [column2], ..." & _
        ") VALUES (" & _
            "@Column1, @Column2, ... )"

        Using cn As New SqlConnection(ConnString), _
              cmd As New SqlCommand(sql, cn)

            cmd.Parameters.Add("@column1", SqlDbTypes.VarChar, 50).Value = TheCustomer.Property1
            cmd.Parameters.Add("@column2", SqlDbTypes.VarChar, 1000).Value = TheCustomer.Property2

            cn.Open()
            cmd.ExecuteNonQuery()
        End Using
    End Sub
End Module

I know you've already heard that separating out your database code is the "right thing to do"tm, but I thought you might also want some more specific reasons why you would want to structure your code this way: 我知道您已经听说,分离数据库代码是“正确的事情”,但是我想您可能还需要一些更具体的原因来解释这种代码结构:

  • Your connection string is kept in one place, so if your database server moves you only need to make one change. 您的连接字符串保存在一个位置,因此,如果您的数据库服务器移动了,则只需进行一次更改。 Even better if this is it's own assembly or config file. 如果这是它自己的程序集或配置文件,那就更好了。
  • If you ever move to a completely different database type you only need to change one file to update the program. 如果您要使用完全不同的数据库类型,则只需更改一个文件即可更新程序。
  • If you have one developer or a DBA who is especially good with sql, you can let him do most of the maintenance on this part of the app. 如果您有一位特别擅长sql的开发人员或DBA,则可以让他在应用程序的这一部分执行大部分维护工作。
  • It makes the code for your "real" objects simpler, and therefore easier to spot when you make a logical design error. 它使“真实”对象的代码更简单,因此在出现逻辑设计错误时也更容易发现。
  • The DAL code might eventually be re-usable if another application wants to talk to the same database. 如果另一个应用程序想要与同一个数据库对话,则DAL代码最终可能会重新使用。
  • If you use an ORM tool most of the DAL code is written for you. 如果您使用ORM工具,则大多数DAL代码都是为您编写的。

There's a few issues here. 这里有几个问题。 First, exactly where are you saving this? 首先,您到底要保存在哪里? You say SQL, but is it a SQL Server, an instance of SQL Express, a Local Data Cache (SQL CE 3.5) or saving via a Web Service to talk to your SQL SERVER. 您说的是SQL,但它是SQL Server,SQL Express实例,本地数据缓存(SQL CE 3.5)还是通过Web服务进行保存以与SQL SERVER进行通信。 These different data sources have different connectivity options/requirements, and in the case of SQL CE there's a few other "gotchas" involved in the SQL itself. 这些不同的数据源具有不同的连接选项/要求,在SQL CE的情况下,SQL本身还涉及其他一些“陷阱”。

Second, are you sure you want to save data into a relational datastore like SQL Server? 其次,确定要将数据保存到SQL Server等关系数据存储中吗? Consider, you could use XML, a data file (text, CSV. etc) or even a custom binary file type instead. 考虑一下,您可以使用XML,数据文件(文本,CSV等),甚至可以使用自定义二进制文件类型。

Since you're working on a windows application, you have a bunch of options on where and how to save the data. 由于您是在Windows应用程序上工作,因此在位置和如何保存数据方面有很多选择。 Until you know where you want to put the data, we'd be hard pressed to help you do so. 在您不知道要将数据放在何处之前,我们将很难为您提供帮助。

I agree with Mike Hofer. 我同意Mike Hofer的观点。 Keeping your class that does your retrieval and persisting of object separate from your business classes is key to having a flexible and robust design. 保持用于进行对象检索和持久化的类与业务类分开是实现灵活而强大的设计的关键。 This is the kind of code you want to be seeing in your GUI or Business layer: 您想在GUI或业务层中看到的是这种代码:

//Populate Customer Objects List with data
IList<Customer> customerList = new List<Customer>()
Customer newCustomer1 = new Customer();
newCustomer.Name = "New Name"
newCustomer.email ="abcd@abcd.com"
customerList.Add(newCustomer1)

//DAL calls
DataAccessClass dalClass = new DataAccessClass ();
dalClass.InsertCustomers(customerList);

Inside your DALClass there should be a method called InsertCustomers(IList customers) and it should have the following code: 在您的DALClass中,应该有一个称为InsertCustomers(IListcustomers)的方法,并且应具有以下代码:

      Public Function InsertCustomers(ByVal objectList As IList(Of Customer)) As Integer
        Dim command As IDbCommand = Nothing
        Dim rowsAffected As Integer = 0
        Dim connection As IDbConnection = New System.Data.SqlClient.SqlConnection(Me.ConnectionString)
        Try 
            connection.Open
            Dim e As IEnumerator = objectList.GetEnumerator

            Do While e.MoveNext

                command = connection.CreateCommand
                command.CommandText = "insert into dbo.Customer(CustomerID,CustomerGUID,RegisterDate,Password,SiteID,Las"& _ 
                    "tName,FirstName,Email,Notes,BillingEqualsShipping,BillingLastName) values (@Cust"& _ 
                    "omerID,@CustomerGUID,@RegisterDate,@Password,@SiteID,@LastName,@FirstName,@Email"& _ 
                    ",@Notes,@BillingEqualsShipping,@BillingLastName)"
                System.Console.WriteLine("Executing Query: {0}", command.CommandText)
                Dim paramCustomerID As IDbDataParameter = command.CreateParameter
                paramCustomerID.ParameterName = "@CustomerID"
                command.Parameters.Add(paramCustomerID)
                Dim paramCustomerGUID As IDbDataParameter = command.CreateParameter
                paramCustomerGUID.ParameterName = "@CustomerGUID"
                command.Parameters.Add(paramCustomerGUID)
                Dim paramRegisterDate As IDbDataParameter = command.CreateParameter
                paramRegisterDate.ParameterName = "@RegisterDate"
                command.Parameters.Add(paramRegisterDate)
                Dim paramPassword As IDbDataParameter = command.CreateParameter
                paramPassword.ParameterName = "@Password"
                command.Parameters.Add(paramPassword)
                Dim paramSiteID As IDbDataParameter = command.CreateParameter
                paramSiteID.ParameterName = "@SiteID"
                command.Parameters.Add(paramSiteID)
                Dim paramLastName As IDbDataParameter = command.CreateParameter
                paramLastName.ParameterName = "@LastName"
                command.Parameters.Add(paramLastName)
                Dim paramFirstName As IDbDataParameter = command.CreateParameter
                paramFirstName.ParameterName = "@FirstName"
                command.Parameters.Add(paramFirstName)
                Dim paramEmail As IDbDataParameter = command.CreateParameter
                paramEmail.ParameterName = "@Email"
                command.Parameters.Add(paramEmail)
                Dim paramNotes As IDbDataParameter = command.CreateParameter
                paramNotes.ParameterName = "@Notes"
                command.Parameters.Add(paramNotes)
                Dim paramBillingEqualsShipping As IDbDataParameter = command.CreateParameter
                paramBillingEqualsShipping.ParameterName = "@BillingEqualsShipping"
                command.Parameters.Add(paramBillingEqualsShipping)
                Dim paramBillingLastName As IDbDataParameter = command.CreateParameter
                paramBillingLastName.ParameterName = "@BillingLastName"
                command.Parameters.Add(paramBillingLastName)
                Dim modelObject As Customer = CType(e.Current,Customer)
                paramCustomerID.Value = modelObject.CustomerID
                paramCustomerGUID.Value = modelObject.CustomerGUID
                paramRegisterDate.Value = modelObject.RegisterDate
                If IsNothing(modelObject.Password) Then
                    paramPassword.Value = System.DBNull.Value
                Else
                    paramPassword.Value = modelObject.Password
                End If
                paramSiteID.Value = modelObject.SiteID
                If IsNothing(modelObject.LastName) Then
                    paramLastName.Value = System.DBNull.Value
                Else
                    paramLastName.Value = modelObject.LastName
                End If
                If IsNothing(modelObject.FirstName) Then
                    paramFirstName.Value = System.DBNull.Value
                Else
                    paramFirstName.Value = modelObject.FirstName
                End If
                If IsNothing(modelObject.Email) Then
                    paramEmail.Value = System.DBNull.Value
                Else
                    paramEmail.Value = modelObject.Email
                End If
                If IsNothing(modelObject.Notes) Then
                    paramNotes.Value = System.DBNull.Value
                Else
                    paramNotes.Value = modelObject.Notes
                End If
                paramBillingEqualsShipping.Value = modelObject.BillingEqualsShipping
                If IsNothing(modelObject.BillingLastName) Then
                    paramBillingLastName.Value = System.DBNull.Value
                Else
                    paramBillingLastName.Value = modelObject.BillingLastName
                End If
                rowsAffected = (rowsAffected + command.ExecuteNonQuery)

            Loop
        Finally
            connection.Close
            CType(connection,System.IDisposable).Dispose
        End Try
        Return rowsAffected
    End Function

It is painful to write the DAL code by hand, but you will have full control of your DAL, SQL and Mapping code and changing any of those will be a breeze in the future. 手工编写DAL代码是很痛苦的,但是您将完全控制DAL,SQL和Mapping代码,将来更改任何这些代码都将是一件轻而易举的事情。

If you don't feel like to write all the DAL Code by hand, you can get a CodeGenerator like Orasis Mapping Studio to generate exactly the same code shown without writing anything. 如果您不想手工编写所有DAL代码,则可以使用诸如Orasis Mapping Studio这样的CodeGenerator来生成完全相同的代码,而无需编写任何内容。 You just need to build your SQL in the tool, map the properties to the paramaters and you are done. 您只需要在工具中构建SQL,将属性映射到参数,就可以完成。 It will generate all the rest for you. 它将为您生成所有其余内容。

Good luck and happy DAL coding! 祝您好运,DAL编码愉快!

I'm with Stephen Wrighton. 我和斯蒂芬·赖顿在一起。 There are a LOT of variables here, and a lot of unanswered questions. 这里有很多变量,还有很多未解决的问题。 If it's SQL, is it even a Microsoft dialect of SQL? 如果是SQL,它甚至是Microsoft的SQL方言吗? Is it Oracle? 是甲骨文吗? MySQL? MySQL的? Something else? 还有吗

In any event, my personal preference is to avoid building SQL in an application if I can, and invoke a stored procedure, even for inserts and updates. 无论如何,我个人的喜好是避免在可能的情况下在应用程序中构建SQL,并避免调用存储过程,即使是插入和更新也是如此。 Then I pass the arguments for the procedure to the ADO.NET command object. 然后,将过程的参数传递给ADO.NET命令对象。 I have this insane idea in my head that SQL belongs in the database. 我脑子里有一个疯狂的想法,即SQL属于数据库。 Perhaps that comes from all that time I spent debugging horrifically written ASP code that spliced SQL strings together back in the Dot Com era. 也许那是因为我花了所有的时间调试水平编写的ASP代码,该代码在点Com时代将SQL字符串拼接在一起。 (Never again.) (再也不。)

If you feel it's absolutely necessary to do so, meet the System.Text.StringBuilder class. 如果您认为这样做是绝对必要的,请参阅System.Text.StringBuilder类。 Learn it. 学习吧。 Love it. 爱它。 Make it your best friend. 使其成为您最好的朋友。

UPDATE: Seeing your response, I see now that you are working with SQL Server. 更新:看到您的答复,我现在看到您正在使用SQL Server。 That makes things much better. 这使事情变得更好。

I'd recommend separating your SQL code into a separate class, away from the actual business class. 我建议将您的SQL代码与实际的业务类分开,放在一个单独的类中。 Some might not agree with that, but it will keep the PURPOSE of the classes clear. 有些人可能不同意这一点,但是它将使课程的目的明确。 (See Separation of Concerns .) (请参阅关注点分离 。)

You want to have your business object handle the business logic, and a separate class that handles the work of getting data into and out of the database. 您想让您的业务对象处理业务逻辑,并希望有一个单独的类来处理将数据移入和移出数据库的工作。 That way, if you have a problem with the serialization logic, you have a far better idea of where to look, and your chances of hosing the business logic are greatly reduced. 这样,如果您在序列化逻辑方面遇到问题,则可以更好地了解在何处查找,并且大大降低了使用业务逻辑的机会。 It also makes your application much easier to understand. 这也使您的应用程序更容易理解。

A little up front effort in writing a few more classes has a HUGE payoff down the road. 在编写更多类的过程中稍作前期的努力就可以取得巨大的回报。

But that's just my opinion. 但那只是我的个人意见。

I prefer the idea of Mike Hofer, to have a Stored Proc in the SQL Server side to handle the actual data updates, and having a separate class to wrap calls to those stored procs. 我更喜欢Mike Hofer的想法,即在SQL Server端拥有一个存储过程来处理实际的数据更新,并拥有一个单独的类来包装对那些存储过程的调用。 Just my 0.02$ 我的0.02美元

Not quite sure what the OP is asking. 不太清楚OP在问什么。

You need to define exactly what you are doing in the "Save" method 您需要在“保存”方法中确切定义正在执行的操作

  • If you are creating a new record in the Save method you need to use an INSERT statement. 如果要在Save方法中创建新记录,则需要使用INSERT语句。
  • If you are updating an existing record in the Save method then you need to use an UPDATE statement. 如果要通过Save方法更新现有记录,则需要使用UPDATE语句。

"Save" methods generally imply that both cases are handled by the procedure. “保存”方法通常意味着两种情况都由该过程处理。

A better method would be to have ("Create" or "Insert") and ("Update" or "Save") methods. 更好的方法是具有(“创建”或“插入”)和(“更新”或“保存”)方法。

Or perhaps have one procedure which handles both. 或者,也许有一个处理这两个过程的程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM