write result of for xml raw query to file vb.net - sql-server

I have a for xml raw select query that returns a xml string in server2005 and i would like to write that string to a file using vb.net.

I found that if you fill a dataset with the result of the sql the first cell is the restult.
How slow was i?!
----------Code Below-------
Dim connection As SqlConnection
Dim adapter As SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
Dim stringxml As String
Dim SqlCon1 As String = "Data Source=SQLSERVER;Initial Catalog=DATABASE;Integrated Security=SSPI;"
connection = New SqlConnection(SqlCon1)
sql = "select * from tblProduct for xml auto"
Try
connection.Open()
adapter = New SqlDataAdapter(sql, SqlCon1)
adapter.Fill(ds)
connection.Close()
stringxml = ds.Tables(0).Rows(0).Item(0)
Using writer As StreamWriter = New StreamWriter("c:\testings\picktoday.xml")
writer.Write(stringxml)
End Using
MsgBox("Done")
Catch ex As Exception
MsgBox(ex.ToString)
End Try

Using strmWrite as System.IO.StreamWriter(filePath)
strmWrite.WriteLine(xmlString)
End Using
Obviously, just fill in the filePath variable with the directory and name of your file. The xmlString variable will be your XML.

I just want to add to the accepted answer when we have a long output we can get data in multiple rows so we can use the following code
dim xmloutput as string
For Each item As DataRow In ds.Tables(0).Rows
xmloutput += item.Item(0)
Next

Related

SQL Server database population pre-existing Data Table and fields (FORM). NO database file

Here is my general understanding of database from what I read so far: Save / Update / Delete to pre-existing file made that binds to form thru SQL.
Here is what I am trying to do - I have a pre-made Data Table in Form with all columns defined. Once app is closed or certain functions ran, I need that data to be saved / updated in SQL (on local). Once app is open I need all that data to be preserved.
So far I have NOT found a single solution to it anywhere most refer to binding to an existing file. When I worked with Excel data transfer cells had to be defined and referenced in form for population.
My assumption is when a database from VB.NET is used, table with values can be created automatically saved/loaded/updated. However this is only my assumption since I never worked with SQL before. I am not sure if I need to manage an actual database file I created with all the values and then bind them to data table. For example DataTable cell XX to database column XX.
Here is what I done so far I have created database and added to my project. I tried few codes and I keep getting Dataset Empty even though there is Data in Table I tried to use DataTable as well but so far nothing has worked.
Please suggest on what I am doing wrong also additional information regards to databases will be great. As per previous I do know how binding works when actual file exist. But creating and managing is confusing to me since I keep thinking there should be a binding file.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "SELECT BN FROM DataTable" ' BN is my column name and DataTable is the name of my Table where data gets populated. This is also confusing to me How does it know which value is what? Is there are space/word/characters requirements?
' adapter.TableMappings.Add("DataTable", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds)
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
Code I use to Create /Save Database. As per previous all columns/formats are pre-made, loaded.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "Select BN FROM DataTable"
adapter.TableMappings.Add("BN", sql)
If DataTable.RowCount > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf DataTable.RowCount = 0 Then
MsgBox("Empty data")
End If
End Sub
Please see more info below:
Data Table columns/format are structured for visual representation.
When User start the App Database can be empty/Can contain Values.
When users Runs certain function Closes App values are save and only values.
If I would you an MS Access I would structure same table/values and cross reference it with form values. Form Values come from outside source and Format/Qty is always known.
Hope this helps to have a cleaner look at my issue. Perhaps SQL is not a right choice for me? Does SQL needs to be build before value manipulation.
UPDATE: I Got rid of the Invalid Object error. Table had to be created 1st as I originally thought. However, My DataSet always comes up as EMPTY when I try to save... Cells do contain BN data as" 1,2, ....) Even if I to remove "If" logic Save and Load table comes out as empty. Something does load because when I try to ADD BN it tells me binding bla bla bla(different issue)
CODE:
Private Sub SaveData()
Dim connetionString As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Dim sql As String = "SELECT BN FROM DataTable_d"
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet()
adapter.TableMappings.Add("BN", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
UPDATE: I got all the things working but I can't save multiple rows..... Could really use some help
In your SQL query remove WHERE DataTable ='. This statement is looking for a column name DataTable which I assume does not exist. The WHERE clause is used to help filter your query. You only use WHERE on column names in your table.
For instance:
SELECT BN FROM DataTable
will return all values from the BN column from DataTable.
Note that if you have multiple columns, the above query will still only return values from BN.
SELECT * FROM DataTable
will return every value in DataTable.
A helpful site to look at documentation for SQL is w3schools.
Let's start with just displaying some data. Add a DataGridView to a Form. You can call LoadData() from a button. I am not very sure of you connection string but give it a try.
Private dt As DataTable
Private sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Private Sub LoadData()
'***EDIT*** Add instantiation line
dt = New DataTable()
'The Using...End Using blocks will close and dispose your database objects
'even if there is an error
Using cn As New SqlConnection(sql)
'You can pass the command text and the connection directly to the constructor
'In the select statement use the actual names of the field and table as they appear in the database.
Using cmd As New SqlCommand("Select BN From [Insert the name of the table in the database]", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
This is the simplest way I can think of to display data. We will proceed with changing the data once this works. If you get an error on cn.Open() We will have to work on the connection string.
****EDIT****
Private Sub TestConnection()
Dim sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Using cn As New SqlConnection(sql)
cn.Open()
End Using
End Sub

How can I use a query written in TSQL in sql server as data source for my dataGridView?

I need a calculated column and to do achieve this I plan on using a query in TSQL from sql server 2014 the problem is I don't know how to use that query as data source for my dataGridView in vb.net. I'm using visual studio 2015. Can someone help point me in the right direction? I just need to display the results of my query in dataGridView. The calculated column will need data from multiple tables and the only way I can create the column is by using a TSQL query in SQL Server.
You cannot bind sql query to DataGridView.DataSource.
But you can with result of your query, for example you can get result as DataTable
Public Function GetData() As DataTable
Dim yourQuery As String = "...."
Using connection As New SqlConnection(yourConnectionString)
Using command As New SqlCommand(query, connection)
' Add parameters if you need
'command.Parameters.AddRange(arrayOfSqlParameters)
connection.Open()
Using adapter As New SqlDataAdapter(command)
Dim data As New DataTable()
adapter.Fill(data)
Return data
End Using
End Using
End Using
End Function
Then use result as DataSource
Dim data As DataTable = GetData()
myDataGridView.DataSource = data
If you don't like DataTable you can load data to the list of your classes which represent data and use it as datasource
Dim data As List<Customer> = GetCustomerData()
myDataGridView.DataSource = data
You need to create a stored procedure for your T-SQL code. And call the same stored procedure from VB.Net
Here is a good example explained for the same.
Using SQL Stored Procedures with VB.NET
Here's a variation of GetData() above. This one uses a DataReader instead which requires less overhead. There's some extra bells and whistles in there which aren't really needed - you really only need rdr = cmd.ExecuteReader()
Function GetDataTable(ByVal SQL As String, Optional ByVal ConnectString As String = "", Optional ByVal SingleRow As Boolean = False) As DataTable ' returns read only Datatable
Try
If ConnectString.Length = 0 Then ConnectString = g.OISConnectString()
Using con As New System.Data.SqlClient.SqlConnection(ConnectString)
Dim rdr As Data.SqlClient.SqlDataReader
con.Open()
Dim cmd As New SqlCommand(SQL, con)
If SingleRow Then
rdr = cmd.ExecuteReader(CommandBehavior.SingleRow Or CommandBehavior.CloseConnection)
Else
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
End If
Dim dt As New DataTable
dt.Load(rdr)
rdr.Close()
Return dt
End Using
Catch ex As Exception
MsgBox(ex.Message, , "GetDataTable")
Return Nothing
End Try
End Function

Grab row of data from SQL Server given value of one cell in a column in that row--Visual Basic

I checked whether a value exists
Dim connectionString = [connection string ]
Using exist As New SqlConnection(connectionString)
Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM Employees WHERE WorkEmail = #WorkEmail", exist)
cmd.Parameters.AddWithValue("#WorkEmail", DataObjects.Contacts.ElectronicAddress.Email)
If cmd.ExecuteScalar > 0 Then
//return row so that I can grab values from it, given column names
How would I go about doing that commented section on the last line?
You should execute your command and then check if it returned any rows.
See Retrieving Data Using a Data Reader
An excerpt slightly tweaked for your use case:
Private Sub HasRows(ByVal connection As SqlConnection)
Using connection
Using cmd As SqlCommand = New SqlCommand("SELECT * FROM Employees WHERE WorkEmail = #WorkEmail", connection)
cmd.Parameters.AddWithValue("#WorkEmail", DataObjects.Contacts.ElectronicAddress.Email)
connection.Open()
Using reader As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
REM Your code to pull the data you want from the returned data goes here
End While
End Using
End Using
End Using
End Sub
In the future try looking through the Microsoft Documents. You will usually find what you need there.

Inserting contents of CSV file into database loses 1 record

I have an application that imports a CSV file (no header row) and writes the contents into a datatable. The datatable is then passed on as a parameter to a function in my DAL that uses the sqlBulkCopy command to write the data to a SQL Server database.
I have run tested the code as both a Webforms and Windows Forms environment and noticed that in both cases the first row of data is lost. Does anyone know why this should be the case and how I can rectify it? Thanks for any help.
I should add that this doesn't happen if the CSV file has a header row.
UI
Dim csvFileFolder As String = "D:\PROJECTS\Letters(DOTNET)\TextFiles\"
Dim csvFileName As String = "quad1a.txt"
Dim connString As String = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" _
& csvFileFolder & ";Extended Properties=""Text;HDR=No;FMT=Delimited"""
Dim conn As New Odbc.OdbcConnection(connString)
'Open a data adapter, specifying the file name to load
Dim da As New Odbc.OdbcDataAdapter("SELECT * FROM [" & csvFileName & "]", conn)
'Then fill a data table, which can be bound to a grid
Dim dt As New DataTable
da.Fill(dt)
grdQuad.DataSource = dt
grdQuad.DataBind()
LettersBLL.TemporaryPatientManager.InsertIntoBulkTable(dt)
DAL
Public Shared Function InsertIntoBulkTable(dt As DataTable) As DataTable
Using myConnection As New SqlConnection(ApplicationConfiguration.ConnectionString)
Using sqlBulkCopy As New SqlBulkCopy(myConnection)
'Set the database table name
sqlBulkCopy.DestinationTableName = "tblBulkInsert"
myConnection.Open()
sqlBulkCopy.WriteToServer(dt)
myConnection.Close()
End Using
End Using
Return Nothing
End Function
Try this...
Dim connString As String = "Driver={Microsoft Text Driver (*.txt; *.csv)};HDR=No;Dbq=" _& csvFileFolder & ";Extended Properties=""Text;HDR=No;FMT=Delimited"""
Added 'HDR=No' to your connection string
Or try specifying your sqlbulkcopy column mappings.
msdn.....
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.columnmappings.aspx
Example.....
http://www.codeproject.com/Articles/18418/Transferring-Data-Using-SqlBulkCopy

VB.Net -- Bulk Insert XML into Existing SQL Server Table

I recently figured out how to export data as XML from SQL Server using VB.Net. I use three SQL statements and dimension an XPath document to add the root tags to the export:
Dim connectionString As String
Dim connection As New SqlConnection
Dim command As New SqlCommand()
Dim sql = "select * from scheduledata for xml auto, elements " & _
"select * from costdata for xml auto, elements " & _
"select * from csintegrationdata for xml auto, elements "
connectionString = "Data Source=(localdb)\v11.0; _
Initial Catalog=localACETest;Integrated Security=True"
connection = New SqlConnection(connectionString)
connection.Open()
command.CommandText = sql
command.Connection = connection
command.CommandType = CommandType.Text
Dim xmlRead As XmlReader = command.ExecuteXmlReader()
Dim xp As New XPath.XPathDocument(xmlRead)
Dim xn As XPath.XPathNavigator = xp.CreateNavigator()
Dim xd As New XmlDocument
Dim root As XmlNode = xd.CreateElement("Data")
root.InnerXml = xn.OuterXml
xd.AppendChild(root)
Dim fStream As New FileStream(Directory, FileMode.Create, FileAccess.ReadWrite)
xd.Save(fStream)
fStream.Close()
I would like to be able to re-import this data into the SQL tables using VB, but I'm having some trouble. The code I'm using is this:
Using sqlconn As New SqlConnection(connectionString)
Dim ds As New DataSet()
Dim sourcedata As New DataTable()
Dim ii As Integer = 0
ds.ReadXml("C:\Users\coopere.COOPERE-PC\Desktop\Test.xml")
sqlconn.Open()
Using bulkcopy As New SqlBulkCopy(sqlconn)
sourcedata = ds.Tables(0)
bulkcopy.DestinationTableName = "CSIntegrationData"
bulkcopy.ColumnMappings.Add("Period", "Period")
bulkcopy.ColumnMappings.Add("Program", "Program")
bulkcopy.ColumnMappings.Add("CostControlAccount", "CostControlAccount")
...
bulkcopy.WriteToServer(sourcedata)
End Using
sqlconn.Close()
End Using
When doing this, I get an error: System.InvalidOperationException: The given ColumnName 'CostControlAccount' does not match up with any column in data source.
I believe the reason for this is because one of the tables that exported to XML has a column full of NULL values which aren't winding up anywhere in the XML. But that won't always be the case -- oftentimes, there will be values.
Considering SqlBulkCopy's columnmappings can't handle accepting null values, how can I handle null values in my Export/Import? I'm also open to a different route entirely.
After much digging, I found this link.
As part of the FOR XML function you can tack on XSINIL at the end to handle null values. The resulting XML is below.
select * from TABLENAME for xml auto, elements XSINIL
<ScheduleWorkPackage xsi:nil="true" />

Resources