Please pardon me for my English grammar.
I'm currently coding a system and I was wondering if you could establish a new connection after you created a database in a server.
This is the Connection String:
Dim DBCon As SqlConnection = New SQLConnection("Data Source=(localdb)\DbLocal;Integrated Security=True")
If I want to create a database I use a command - the database name is bounded after a textbox, it goes like:
Dim dbName As String = txtdbName.Text
myCommand = "CREATE database " & dbName
The database gets created, but after I start a query that creates a table - the table does not save in the created database. So with my beginner skills in VB.Net and MSSQL, I deduced it was because of my Connection String, so I tried messing with it:
Dim myConnectionString As SqlConnection = New SqlConnection("Data Source=(localdb)\DbLocal;Database=" & dbName & ";Integrated Security=True;Pooling=False")
I wrote the above code before the create a table query, but after I run it, the tables I created in the query didn't go to the database. I was wondering if there's a 'right' way to do this. I tried mixing different codes that I found online, but they produce the same result.
Edit: My create table query:
myCommand = "CREATE TABLE tblPerson (PersonID int, LastName varchar(300), FirstName varchar(300), Address varchar(300), City varchar(300))"
The way I would do this is to add a USE statement before the CREATE TABLE. So the CREATE TABLE command would look like this:
"USE " & dbName & ";
GO
CREATE TABLE ..."
EDIT: As pointed out in the comments, the GO separator cannot be used in a .NET SQL Command.
Instead one can use three-part naming to specify the database like this:
"CREATE TABLE " & dbName & ".dbo.MyTable ( ..."
Or use SMO which does allow one to use the GO separator. This technique is thoroughly described in the accepted answer to this question.
Related
I have an access database for which I need to run a query that is available in postgres DBs, I was wondering if there is a possible that this can be accomplished:
Insert into Table (Col1,Col2...) values(Val1,Val2,...) returning * (ore even just an id defining that specific set of data that was just inserted)?
I'm using c# to communicate to the DB.Anything would help, thank you.
The code I basically use is the following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.OleDb;
namespace Testquery1
{
class Program
{
static void Main(string[] args)
{
string query = "INSERT INTO Table ( Val1, Val2, Val3 ) values(14,2,1)";
Test1 queryselect = new Test1();
queryselect.dataconnection(query);
}
}
class Test1
{
public OleDbConnection connection = new OleDbConnection();
string path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string fileloc = #"DataBase.accdb";
string provider = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=";
public void dataconnection(string query)
{
connection.ConnectionString = provider + path + fileloc;
Console.WriteLine(connection.ConnectionString);
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = query;
command.ExecuteNonQuery();
connection.Close();
}
}
}
Unfortunately with .net you cannot do a append or make table query between two different connections.
However, you CAN in Access.
If you have a working PostgreSQL SQL query that returns records, then you can simple save that query in Access (as a pass-through query.
You can now use that query in Access and send it to a NEW local table in Access. (Access supports this concept, .net does not)
You can thus either append or “make table” of that data.
And more interesting is you can even append between different connections in Access. So you can append from a PostgreSQL table to say a MySQL, or Oracle or FoxPro table inside of access.
Again, you can’t do this in .net.
So, assume a working raw SQL (PostgreSQL format) query that works in PostgreSQL? Take that SAME working query and save it in Access as a pass-through query.
Then in Access you can append to a table in Access (assuming same table structure with:
VBA (Access code)
Dim strSQL as string
strSQL = "INSERT INTO LocalTable SELECT * from QryPassR"
Currentdb.Execute strSQL
And if you want to MAKE a new table in Access with the SAME structure, so make table (not append), you can go:
Dim strSQL as string
strSQL = " SELECT * INTO LocalTable FROM qryPassR"
Currentdb.Execute strSQL
You can also in VBA code change the PostgreSQL to include criteria for that select.
(air code - does not take into account SQL injection issue).
Dim strCity as string.
strCity = inputbox("What city to pull from PostGres?")
dim strSQL as string
strSQL = "select * from tbleHotels where City = '" = strCity & "'"
With currentdb.QueryDefs("QryPassR"
.SQL = strSQL
End with
strSQL = "INSERT INTO LocalTable SELECT * from QryPassR"
Currentdb.Execute strSQL
‘ above will copy all the records from PostGreSQL of city = Edmonton into the Access table (called local table in this example).
And as noted, you not limited to “LocalTable” being a access table, it could be a FoxPro table, MySQL, SQL server etc. So you not limited to JUST using Access tables in the above with your given SQL. So any linked table you have in Access can be used – including ones that point to other database systems.
If you must use .net, then you have to:
Connect to first database.
Execute query to pull and fill a datatable.
Connect to second database.
Create (open) a data table based on second database.
Loop (iterate) each row from first connection datatable and copy the row into the second datatable (based on 2nd connection).
You have to do a row by row copy. (but there is ImportRow method of the .net datatable, so you don’t have to loop by a column by column copy.
(but you have to loop row by row).
In Access this looping is not required and in fact you can use SQL commands that operate on both tables, including as per above the make table and append, and you can even do relation joins between such tables - even those based on different connections (data sources).
Edit
Based on comments, it looks like the simple question is:
After I insert a row into Access, how can I get the last ID (identity) of that insert?
The follow vb.net code will do this:
Imports System.Data.OleDb
Dim MyCon As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test2\test44.accdb")
MyCon.Open()
Dim strSQL As String = "insert into tblHotels2 (City) VAlues('Edmonton')"
Dim cmd As New OleDb.OleDbCommand(strSQL, MyCon)
Dim r As Integer
cmd.ExecuteNonQuery()
cmd.CommandText = "select ##IDENTITY"
r = cmd.ExecuteScalar
Debug.Print(r)
Output = last PK id (autonumber)
I have the following code and Insert-statement.. and connection.
SqlConnection con = new SqlConnection();
con.ConnectionString = ("Data Source=DESKTOP-PGHMM6M;Initial Catalog=LocalUsers;Integrated Security=True");
con.Open();
string st = "INSERT INTO data(Username, Password, Hash, EncryptedPassword) VALUES (#Username, #Password, #Hash, #EncryptedPassword)";
SqlCommand cmd = new SqlCommand(st, con);
cmd.Parameters.AddWithValue("#Username", Username);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
cmd.Parameters.AddWithValue("#Hash", savedPasswordHash);
cmd.Parameters.AddWithValue("#EncryptedPassword", FinalEncryptedPass);
cmd.ExecuteNonQuery(); // invalid object name 'data' < where is this object?
con.Close();
When I run the program it returns the following error:
Invalid object name 'data'
I'm not sure what I did to create this situation. I was fulling around with the "stand-alone sql features" in Visual studio 2017, and I'm not sure where to start, to get back on track to use a local SQL Management Server Studio db that I created.
I found a previous question with the following::
Right click the database project --> Properties
Click Debug
Under Target Connection String, click Edit and select the correct database server
Create a new stored procedure
But I'm not sure what any of this is referring to ^.. any pointers?
welcome to stackoverflow.com
it says you do not have a table (in which you are inserting data) name : "data"...
you must have a database name "LocalUsers". in this database,
create a table name : "data" (with given fields) and you are good to go.
I would like to create a database in SQL server using VBA (Excel) just the first time that I will run the code. So the second time I run the code, the database will exist, and it will not create another one.
#abarisone
`Public Sub CreateDBTable()
Dim dbConnectStr As String
Dim Catalog As Object
Dim cnt As ADODB.Connection
Dim dbName As String
Dim tblName As String, ServerName As String, UserID As String, pw As String
tblName = shControl.Range("B5") 'Table Name
ServerName = "SERVICESWS15" 'Enter Server Name or IP
dbName = shControl.Range("B4") 'Enter Database Name
UserID = "" 'Leave blank for Windows Authentification
pw = "" 'Leave blank for Windows Authentification
dbConnectStr = "Provider=SQLOLEDB;Data Source=" & ServerName & ";Initial Catalog=" & dbName & ";User Id=" & UserID & ";Password=" & pw & ";"
Set Catalog = CreateObject("ADOX.Catalog")
Catalog.Create dbConnectStr
Set Catalog = Nothing
Set cnt = New ADODB.Connection
With cnt
.Open dbConnectStr
.Execute "CREATE TABLE " & tblName & " (KEY nvarchar(100) NOT NULL, " & _
"Date nvarchar(100) NOT NULL, " & _
"PRIMARY KEY (KEY));"
End With
Set cnt = Nothing
End Sub
`
There is an error in this line:
Catalog.Create dbConnectStr
Error: No such interface supported
It's not very complicated. First make sure that you are referring to the appropriate ADO library like here on the screenshot.
Then your have certain building blocks you will have to use: first make a Connection object (with a connection string), then make a Command object, and last but not least use the ExecuteNonQuery method of Command on your connection object. It does what the name says: executes an SQL command without having a RecordSet as a return object. See examples in the documentation starting from here.
I have not tried it before, but for this to happen without error, you will probably have to set your connection string to the system database called "Master" if working on MS SQL Server.
Of course, the SQL commands you will have to execute are (1) check if the database exists, (2) create db and tables if not.
Then you can create your "normal" Connection object to your database.
WARNING: to be able to create a database, your technical user defined in the VBA script must have high (system admin) privileges which is definitely a HUGE RISK even if you protect your excel. If it's not a sandbox environment, DO NOT DO IT!
I am working on an application which backs up database tables and stores their data as CSV. When I want to restore a table back to the database I use a 'model' table which creates an existing table based on the model.
However there are multiple structures of these tables and I would like to generate the tables' 'Create' script and save it somewhere for restoring purposes.
Is there anyway for this? I am only interested to do this via coding and not sql script because we are using both SQL Server and Oracle and this process will be automated for more than 3000 tables.
In the code below I create the table based on a table model:
If ProductData.Tables(0).Rows(0).Item(0) = 0 Then 'Does not exist
'Create table based on a model
Dim sqlCopyFromModel As New SqlCommand("SELECT TOP 0 * INTO " & sFileName & " FROM s_20130702;", con)
con.Open()
Dim i As Integer = sqlCopyFromModel.ExecuteNonQuery()
con.Close()
'Enter data from CSV file
Dim sqlInsertDataFromCSV As New SqlCommand("BULK INSERT " & sFileName & " FROM '" & txtFilePath.Text.Trim & "' WITH (FIELDTERMINATOR = ',', ROWTERMINATOR = '\n', FIRSTROW=2 )", con)
con.Open()
sqlInsertDataFromCSV.ExecuteNonQuery()
con.Close()
MsgBox("success")
In Oracle you can use builtin package DBMS_METADATA where the function GET_DDL can give you the DDL ("create script") needed to create the table.
http://docs.oracle.com/database/121/ARPLS/d_metada.htm#ARPLS66885
SELECT DBMS_METADATA.GET_DDL('TABLE','EMP','SCOTT')
FROM DUAL;
(If you are trying to do something that is database independent and works both on SQL Server and Oracle, then you'd better not use "TOP 0" ;-)
We need to find a way to programatically ****link all the tables in a SQL Server database to an access db. We will be invoking this access database from a program that uses .net/SQL Server 2008.
While invoking the application we would like to add the linked tables so that the users can just run the reports/modules from access without having to worry about linking the tables. Is there a way we can do this?
Here are some notes.
Dim sLocalName As String
Dim tdf As TableDef
Dim rs As dao.Recordset
''This is a basic connection string, you may need to consider password and so forth
cn = "ODBC;DSN=TheDSNName;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=TheDatabaseName;"
''All fields from tables
strSQL = "SELECT TABLE_CATALOG, " _
& "TABLE_SCHEMA, " _
& "TABLE_NAME, " _
& "TABLE_TYPE " _
& "FROM [" & cn & "].INFORMATION_SCHEMA.tables " _
& "WHERE TABLE_TYPE = 'BASE TABLE'"
Set rs = CurrentDb.OpenRecordset(strSQL)
Do While Not rs.EOF
sLocalName = rs!TABLE_SCHEMA & "_" & rs!TABLE_NAME
With CurrentDb
If DLookup("Name", "MSysObjects", "Name='" & sLocalName & "'") <> vbNullString Then
If .TableDefs(sLocalName).Connect <> cn Then
.TableDefs(sLocalName).Connect = cn
.TableDefs(sLocalName).RefreshLink
End If
Else
''If the table does not have a unique index, you will neded to create one
''if you wish to update.
Set tdf = .CreateTableDef(sLocalName)
tdf.Connect = cn
tdf.SourceTableName = rs!TABLE_NAME
.TableDefs.Append tdf
.TableDefs.Refresh
''This will produce a message box if the table does not have a unique index
''DoCmd.TransferDatabase acLink, "ODBC Database", cn, acTable, rs!TABLE_NAME, sLocalName
End If
End With
rs.MoveNext
Loop
You'll need an ODBC connection to the SQL database. Once this connection ready, you can use it for all tables that you want to link:
DoCmd.TransferDatabase acLink, _
"ODBC Database", _
myODBCconnection, _
myDatabaseName, _
acTable, _
myTableName
I guess you can declare your ODBC connector "on the fly", as proposed here for example.
To enumerate your tables, you have the following options:
Enumerate them in the code: one transferDatabase line per table
Save the table names in a local table, and browse the table
Save the table names in a file (text, xml) anywhere on the network and browse the file
Access the system table on the server that holds the table list, and browse the table
Use the ADOX object to browse all tables in your database server: be carefull not to include system tables. This solution might be also quite confusing because you'll have to first open an ADODB connection to your database, and you'll then use an ODBC connection to open the tables
In all cases, this procedure shall be launched with the autoexec macro, meaning that links will be created\updated each time the user opens the mdb client.
You would use ADOX to do the actual linking.
As far as enumerating the tables in a database you are connected to, you could do something as simple as running this query against your SQL Server, but there are a lot of ways to skin that cat:
SELECT * FROM INFORMATION_SCHEMA.TABLES
You can achieve the equivalent by using a Linked Server in SQL Server that points to the Access db. This will give you access to all the tables in the Access db so that you can reference them like:
Select ..
From [LinkedServerName]...[AccessTableName]
Btw, a linked server may be overkill for what you want. Look into the OPENROWSET function which effectively let's you pass a connection string.
EDIT: I originally read the question to literally mean "link tables in SQL Server to access" which I translated to mean from SQL to Access. So, given that, my solution would apply. However, if the desire is to go from Access to SQL, then that is different and other solutions presented would be more appropriate.