Possible to query As400 DB2 via VB.Net without a PRG? - vb.net

After spending a few days researching and trying to figure this out solo, I could really use some help.
I'm trying to query the As400's database directly from .Net without the use of a As400 program file. I have very little support other than "go ahead and try" from the As400 administrators (I'm being told what I'm attempting hasn't been done here before).
I'd really like to use CWBX. The code below successfully connects, but I could really use a pointer in the right direction on how to build a query:
Dim As400 As New AS400System
Dim AsProgram As New cwbx.Program
Dim AsCommand As New cwbx.Command
Dim strQuery As String
As400.Define("AS400")
As400.UserID = ""
As400.Password = ""
As400.IPAddress = ""
As400.Connect(cwbcoServiceEnum.cwbcoServiceRemoteCmd)
If As400.IsConnected(cwbcoServiceEnum.cwbcoServiceRemoteCmd) = 1 Then
MsgBox("Valid Connection")
Else
MsgBox("Invalid Connection")
Exit Sub
End If
'-----------------------------------------------------------------------------------------
'Trying to figure out first if this syntax is correct, and if so... where/how to call it??
'-----------------------------------------------------------------------------------------
strQuery = "SELECT * FROM Library.File WHERE FILEFIELD='Criteria'"
' ---
AsProgram.LibraryName = ""
AsProgram.ProgramName = "" '?
AsProgram.system = As400
'Assuming this will end up being a program call?
'AsProgram.Call()
As400.Disconnect(cwbcoServiceEnum.cwbcoServiceRemoteCmd)
I'm very open to any other methods/suggestions. I've looked for guides from IBM's site as well as MSDN and neither actually do direct querying without the use of an As400 program file. Is this even possible?

Here is a simple console app that will retrieve all the records from one table and display the row count.
Imports System.Data.OleDb
Module Module1
Sub Main()
Dim cmd As New OleDbCommand
Dim table As String = "YOUR TABLE"
cmd.CommandText = "SELECT * FROM " & table
Dim ip As String = "YOUR AS/400 IP GOES HERE"
Dim user As String = "YOUR USER ID"
Dim pass As String = "YOUR PASSWORD"
Dim defaultLib As String = "YOUR LIBRARY"
Dim connstring As String = "Provider=IBMDA400;" & _
"Data Source=" & ip & ";" & _
"Force Translate=0;" & _
"Default Collection=" & defaultLib & ";" & _
"User ID=" & user & ";" & _
"Password=" & pass
cmd.Connection = New OleDbConnection(connstring)
cmd.Connection.Open()
Dim dr As OleDbDataReader = cmd.ExecuteReader
Dim dt As New DataTable
dt.Load(dr)
Console.WriteLine(dt.Rows.Count)
Console.WriteLine("Press ENTER to close...")
Console.ReadLine()
End Sub
End Module

The remotecmd service is basically a Rexcd daemon. Not sure why you're messing with that when you want to simple query a DB table. The integrated DB in IBM i is accessible via ODBC, OLEDB, JBDC and most importantly for you a ADO.NET provider.
http://www-03.ibm.com/systems/power/software/i/access/windows/dotnet.html
All of the above mentioned drivers are available in the IBM i Access software. Note that while some of the IBM i Access features are chargeable, ex 5250 emulation, and you must have bought a license; the data access providers are not.
Included in the IBM i Access package is a collection of documentation known as the "Programmers Toolkit"
An example using the .NET data provider from that toolkit:
Public Sub Example()
Dim cn As iDB2Connection = New iDB2Connection("DataSource=mySystemi;")
Dim da As New iDB2DataAdapter("select * from mylib.mytable", cn)
End Sub
Lastly note that the (free) .NET provider doesn't support Microsoft's Entity Framework (EF). If you need EF support, you'll have to pay for DB2 Connect
http://www-03.ibm.com/software/products/en/db2-connect-family

Related

Allow others on shared drive to use access odbc connection

I have an Access file with ADD and UPDATE queries that is linked to an SQL database of some sort (Orderwise). I'm building the reports and things, but someone else in our company will end up using it - possibly a variety of people - therefore I've put it on a Shared Drive.
However, when I access it from another computer (tried to demonstrate it to the Ops manager) it loses the connection to the SQL database, despite both computers having access to that drive too. I'm new to this but I think the ODBC file / connection it relies on is somewhere in the computer that built the database - the error message is ODBC connection to 'Orderwise 2' failed..
I've tried researching it but haven't found anything very conclusive, it seems to involve .mdb files but I don't know where those are, and hunting through the control panel settings thing doesn't give an option to move the odbc to a shared drive.
How can I share this database so everyone on the shared drive can use the live data connection?
Below is code to connect SQL Database and run commands.
Private Sub cmdTest_Click()
'Add reference Microsoft ActiveX Data Objects 2.1 Library
'Fix SQL Server Connection ERROR! See below link
'https://blog.sqlauthority.com/2009/05/21/sql-server-fix-error-provider-named-pipes-provider-error-40-could-not-open-a-connection-to-sql-server-microsoft-sql-server-error/
'Declare variables'
Dim objMyConn As ADODB.Connection
Dim objMyCmd As ADODB.Command
Dim objMyRecordset As ADODB.Recordset
Set objMyConn = New ADODB.Connection
Set objMyCmd = New ADODB.Command
Set objMyRecordset = New ADODB.Recordset
Dim strEmpID As String, strEmpName As String
Dim JoiningDate As Date
Dim eSalary As Integer
Dim myRate As Double
'Open Connection'
objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=192.168.0.150;User ID=sa;Password=saDBpassword;"
objMyConn.Open
'Another provider
'Provider=sqloledb;Data Source=192.168.0.150,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=myUsername;Password=myPassword;
'Set and Excecute SQL Command'
Set objMyCmd.ActiveConnection = objMyConn
' Insert data to SQL Database table.
strEmpID = InputBox("Enter Employee ID:", "Employee ID", "HO-300")
strEmpName = InputBox("Enter Employee Name:", "Employee Name", "Mr. SQL")
JoiningDate = InputBox("Enter Joining Date:", "Joining Date", Date)
eSalary = InputBox("Enter Salary:", "Salary", 10000)
myRate = InputBox("Enter Rate:", "Rate", 11.11)
objMyCmd.CommandText = "INSERT INTO [TestDB].[dbo].[tblEmpInfo] (EmpID, EmpName, jDate, Salary, HourRate) Values('" _
& strEmpID & "', '" _
& strEmpName & "', '" _
& JoiningDate & "', " _
& eSalary & ", " _
& myRate & ")"
objMyCmd.CommandType = adCmdText
objMyCmd.Execute 'Execute SQL command
End Sub
You have to add ActiveX Data Objects 2.5 Library to reference. I am using MS-Access-2013. Object reference may varies depending on MS-Access versions.
Please read this article carefully to troubleshoot network service barrier. SQL Server Fix Error.

Storing information in the access database

Hi I'm trying to store the information of a new element in the datagrid, In the app is open the information is there, but when we close it and open it again, all the new information dissapear, can someone help?
Dim cmdSql As String
'If txtNumero.Text = "1" Then
cmdSql = "INSERT INTO Fatura (Cliente, Data, ValorTotal) " &
"VALUES ('" & txtCliente.Text & "', #" &
dataFatura.Value.ToString("dd/MM/yyyy") & "#, " &
Replace(txtValorTotal.Text.ToString, ",", ".") & ")"
GerirLigacao.ExecutarCmdSQL(cmdSql)
cmdSql = "SELECT TOP 1 Numero FROM Fatura ORDER BY Numero DESC"
Dim r As DataSet = GerirLigacao.obterDados(cmdSql)
txtNumero.Text = r.Tables(0).Rows(0).Item("Numero")
txtNrFatura.Text = txtNumero.Text
Dim msg = "Fatura guardada com sucesso"
Dim titulo = "Guardar"
Dim botoes = MessageBoxButtons.OK
Dim icone = MessageBoxIcon.Information
MessageBox.Show(msg, titulo, botoes, icone)
Gerirligacao
Public Shared Sub ExecutarCmdSQL(ByVal comando As String)
Try
Dim cmdSql As New OleDbCommand(comando, ligacao)
cmdSql.ExecuteNonQuery()
Catch ex As Exception
Dim msg = "Aconteceu um erro de execução." & vbNewLine
Dim botoes = MessageBoxButtons.OK
Dim icone = MessageBoxIcon.Error
MessageBox.Show(msg & ex.Message, "ERRO", botoes, icone)
End Try
End Sub
Look for the database file in the Solution Explorer, click on it and in the Properties grid set Copy To Output Directory to Copy If Newer
More info: https://social.technet.microsoft.com/wiki/contents/articles/53248.visual-studio-copying-files-to-debug-or-release-folder.aspx
Now might also be a good time to tell you that you could make some serious improvements to your database access code; this way you're doing it makes things very hard work and the code is highly insecure (take a read of http://bobby-table.com for more info). Microsoft used to have a great set of walkthroughs at http://msdn2.microsoft.com/en-us/library/fxsa23t6(vs.80).aspx - that documentation has now been archived (being at least 15 years old) and I cant download them on a cellphone to check it "creating a simple data application" is still prt of it. There are a good number of tutorials on YouTube about how to use tableadapters and datasets if that's the route you want to use, though the modern technology (and widest spread of knowledge) these days is probably available for Entity Framework. Google for "getting started with entity framework" and take a look; I'd highly recommend you go this way than your existing route of using weakly typed datasets and direct sql queries

Executing an SQL query in an Access Database in VB.NET

I have already posted one question about this piece of code before lol. But now I am having a different problem and need help with it. Basically this is code for a search button on a Windows Form coded in VB.NET.
Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click
Dim cnnOLEDB As New OleDbConnection
Dim cmdOLEDB As New OleDbCommand
Dim strConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & System.Environment.CurrentDirectory & "\All Keyed Up, Lock & Safe, LLC.accdb"
cnnOLEDB.ConnectionString = strConnectionString
cnnOLEDB.Open()
Dim Connection As New SqlClient.SqlConnectionStringBuilder
Connection.DataSource = "file:///C:\Users\thelukester145\Documents\All%20Keyed%20Up\All%20Keyed%20Up,%20Lock%20&%20Safe,%20LLC.accdb"
Dim objSQLConnection = New SqlClient.SqlConnection(Connection.ConnectionString)
Dim cmd As New SqlCommand()
Dim myTable As New DataTable()
Dim SearchFor = SearchBox.Text
If AddressButton.Checked Then
cmd.Connection = objSQLConnection
cmd.CommandText = "SELECT * FROM [McDonald's-Corporate Stores] WHERE [Address] LIKE '%" & SearchFor & "%'"
Dim myAdapter As New SqlDataAdapter(cmd)
myAdapter.Fill(myTable)
DataGrid.DataGridView1.DataSource = myTable
ElseIf NumberButton.Checked Then
cmd.Connection = objSQLConnection
cmd.CommandText = "SELECT * FROM [McDonald's-Corporate Stores] WHERE [McOpCo#] LIKE '%" & SearchFor & "%'"
Dim myAdapter As New SqlDataAdapter(cmd)
myAdapter.Fill(myTable)
DataGrid.DataGridView1.DataSource = myTable
End If
DataGrid.Show()
cnnOLEDB.Close()
End Sub
The database that is attempting to be searched is a database of customers for our family buisness. I am trying to search by either the address or store number of our customer. I've worked through who knows how many fatal errors but the newest one has me sort of stumped. It is crashing on myAdapter.Fill(myTable). The error message it gives is this:
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 25 - Connection string is not valid)
Any help would be much appreciated :)
Well, you are freely mixin OleDb classes with SqlClient classes. The two are for different database types. OleDb is needed for Access, SqlClient classes are used for Sql Server.
So you need to change all the classes SqlCommand, SqlCommandBuilder, SqlDataAdapter,SqlConnectionStringBuilder with the corresponding classes OleDbCommand, OleDbCommandBuilder, OleDbDataAdapter, OleDbConnectionStringBuilder
Infact, the error message is emitted by the SqlClient library that tries to use your connection string as it was a connectionstring for an SQL Server database and, of course, it fails to find it.
Also, I am not sure about that, but probably the DataSource property doesn't need the prefix file:/// and the Encoding of spaces with %20

source name not found and no default driver specified 111

Hi Im trying to access MS ACCESS DB via VB and I get this error
ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
I have done:
Change IIS manager -application pool App32 bits to true
Downloaded DB drivers for Access
Install Access Client
Nothings working at the moment, I've tried from 2 diffrent computers
This is my code
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim vConnectionStringX As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\1767631\db_Assign_2.accdb;Persist Security Info=False;"
Dim rtfConn As New Data.Odbc.OdbcConnection(vConnectionStringX)
rtfConn.Open()
Dim cusFName As String = TextBox1.Text
Dim cusLName As String = TextBox2.Text
Dim cusTP As String = TextBox3.Text
Dim cusEmail As String = TextBox4.Text
Dim vSQL As String = "Insert into Customer(FirstName, LastName, Telephone, Email) Values (" & cusFName & "," & cusLName & "," & cusTP & "," & "cusEmail"")"
Try
Dim rtfSQLCMD As New Data.Odbc.OdbcCommand
rtfSQLCMD.Connection = rtfConn
rtfSQLCMD.CommandText = vSQL
Dim vResult As Integer = rtfSQLCMD.ExecuteNonQuery
MessageBox.Show("Customer registered! " & vResult)
Catch ex As Data.Odbc.OdbcException
Dim vErMsg As String = "*** Error occured while registering the customer ***" & ControlChars.NewLine
End Try
rtfConn.Close()
End Sub
Plese help me!
Your connection string is for OleDb connections and it is not valid for Odbc. you must use something like this for OdbcConnection:
Dim vConnectionStringX As String = "Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\db1.mdb"
you also need to save your access database as '.mdb' file (eg Ms Access 2000 - 2003 format)
Note: There is also another option: if you don't have a reason to use Odbc, why you don't use OleDb which is usually used for microsoft access database? if you want to use OleDb you should use your original(current) connection string but use OleDbConnection for your connection variable and OleDbCommand for your command variable and so on.
Also, make sure you have updated VB6 for service pack SP6. It's required to handle MS Access 2000 and later.

Inserting variables into a query string - it won't work!

Basically i have a query string that when i hardcode in the catalogue value its fine. when I try adding it via a variable it just doesn't pick it up.
This works:
Dim WaspConnection As New SqlConnection("Data Source=JURA;Initial Catalog=WaspTrackAsset_NROI;User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
This doesn't:
Public Sub GetWASPAcr()
connection.Open()
Dim dt As New DataTable()
Dim username As String = HttpContext.Current.User.Identity.Name
Dim sqlCmd As New SqlCommand("SELECT WASPDatabase FROM dbo.aspnet_Users WHERE UserName = '" & username & "'", connection)
Dim sqlDa As New SqlDataAdapter(sqlCmd)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
For i As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(i)("WASPDatabase") Is DBNull.Value Then
WASP = ""
Else
WASP = "WaspTrackAsset_" + dt.Rows(i)("WASPDatabase")
End If
Next
End If
connection.Close()
End Sub
Dim WaspConnection As New SqlConnection("Data Source=JURA;Initial Catalog=" & WASP & ";User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
When I debug the catalog is empty in the query string but the WASP variable holds the value "WaspTrackAsset_NROI"
Any idea's why?
Cheers,
jonesy
alt text http://www.freeimagehosting.net/uploads/ba8edc26a1.png
I can see a few problems.
You are using concatenation in a SQL statement. This is a bad practice. Use a parameterized query instead.
You are surrounding the password with single quotes. They are not needed and in fact, I'm surprised it even works assuming the password itself does not have single quotes.
You should surround classes that implement IDisposable with a Using block
You should recreate the WASP connection object in GetWASPcr like so:
Public Sub GetWASPAcr()
Dim username As String = HttpContext.Current.User.Identity.Name
Dim listOfDatabaseConnectionString As String = "..."
Using listOfDatabaseConnection As SqlConnection( listOfDatabaseConnectionString )
Using cmd As New SqlCommand("SELECT WASPDatabase FROM dbo.aspnet_Users WHERE UserName = #Username")
cmd.Parameters.AddWithValue( "#Username", username )
Dim dt As New DataTable()
Using da As New SqlDataAdapter( cmd )
da.Fill( dt )
If dt.Rows.Count = 0 Then
WaspConnection = Null
Else
Dim connString As String = String.Format("Data Source=JURA;Initial Catalog={0};User Id={1};Password={2};" _
, dt.Rows(0)("WASPDatabase") _
, ConfigurationManager.AppSettings("WASPDBUserName") _
, ConfigurationManager.AppSettings("WASPDBPassword"))
WaspConnection = New SqlConnection(connString);
End If
End Using
End Using
End Using
End Sub
In this example, listOfDatabaseConnectionString is the initial connection string to the central database where it can find the catalog name that should be used for subsequent connections.
All that said, why would you need a class level variable to hold a connection? You should make all your database calls open a connection, do a sql statement, close the connection. So, five database calls would open and close a connection five times. This sounds expensive except that .NET gives you connection pooling so when you finish with a connection and another is requested to be opened, it will pull it from the pool.
Your string passed into the constructor for this SqlConnection object will be evaluated when the class is instantiated. Your WASP variable (I'm assuming) won't be set until the method you have shown is called.
Might want to quit looking one you have found your database:
For i As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(i)("WASPDatabase") Is DBNull.Value Then
WASP = ""
Else
WASP = "WaspTrackAsset_" + dt.Rows(i)("WASPDatabase")
break
End If
Next
[link text][1]You are building your string on the fly by adding the value of a column to a string. So, for the row in question for the column "WASPDatabase" was tacked on to your string. So you got what it had. On another note, your earlier query of "select ... from ... where ..." where you are manually concatinating the string of a variable makes you WIDE OPEN to SQL-Injection attacks.
Although this link [1]: how to update a table using oledb parameters? "Sample query using parameterization" is to a C# sample of querying with parameterized values, the similar principles apply to most all SQL databases.
At the time you're creating the new connection, WASP is holding the value you want it to be holding? It is a string data type? Try adding .ToString after WASP and see if that helps anything.
Interesting problem. =-)
The problem is, as Paddy already points out, that the WaspConnection object gets initialized before you even have the chance to call GetWASPAcr. Try this:
Public Sub GetWASPAcr()
'[...]
End Sub
Dim _waspConnection As SqlConnection
Public Readonly Property WaspConnection As SqlConnection
Get
If _waspConnection Is Nothing Then
GetWASPAcr()
_waspConnection = New SqlConnection("Data Source=JURA;Initial Catalog=" & WASP & ";User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
End If
Return _waspConnection
End Get
End Property