I have been running into trouble executing SQL code in VBA Access when I refer to certain Table names.
For example,
INSERT INTO TempTable (ClientName) SELECT DISTINCT 1_1_xlsx.ClientName FROM 1_1_xlsx'<--does not work
The code works fine when I changed the Table name from 1_1_xlsx to Stuff.
INSERT INTO TempTable (ClientName) SELECT DISTINCT Stuff.ClientName FROM Stuff '<--works
I have no idea why the first query results in a syntax error and the second code is runs fine even when they refer to the same thing. I suspect it should be the naming conventions but I could not find any concrete answers.
Also, are there any ways that I could use 1_1_xlsx as my table name? Or am I just writing my query wrong?
try this:
INSERT INTO TempTable (ClientName) SELECT DISTINCT [1_1_xlsx].ClientName FROM [1_1_xlsx]
In many SQL based databases you can't have a table name or field name that starts with a number.
I suspect this is the underlying reason for your problem. Although Access will allow it, I have seen it cause problems in the past.
The problem is the number at the beginning of the table name. That is bad -- because it confuses the parser.
This is a bad table name, but SQL allows you to define table aliases. And, in this case, you don't even need to repeat the table name. So, here are two simple solutions:
INSERT INTO TempTable (ClientName)
SELECT DISTINCT ClientName
FROM 1_1_xlsx;
Or:
INSERT INTO TempTable (ClientName)
SELECT DISTINCT t.ClientName
FROM 1_1_xlsx as t
There is no reason to use the complete table name as an alias. That just makes the query harder to write and to read.
Related
I do not fully understand the "USE" statement in Transact-SQL and how it affects the scope of temp tables. I have a user-defined table type in one database but not another, and I've found I need to "USE" that database in order to define a table of that type. Earlier in the query, I define a temporary table. After the "USE" statement, SSMS does not recognize the temp table as a valid object name, however I can still query from it without error.
The skeleton of my SQL query is as follows:
USE MYDATABASE1
[... a bunch of code I did not write...]
SELECT * INTO #TEMP_TABLE FROM #SOME_EARLIER_TEMP_TABLE
USE MYDATABASE2
DECLARE #MYTABLE MyUserDefinedTableType -- this table type only exists in MYDATABASE2
INSERT INTO #MYTABLE(Col1, Col2)
SELECT Col1, Col2 FROM (SELECT * FROM MYDATABASE2.dbo.SOME_TABLE_VALUED_FUNCTION(param1, param2)) T
SELECT A.*, B.Col2
FROM #TEMP_TABLE A
CROSS APPLY DATABASE2.dbo.SOME_OTHER_TABLE_VALUED_FUNCTION(#MYTABLE, A.SomeColumn) B
In the last SELECT statement, SSMS has red squiggly lines under "A.*" and "#TEMP_TABLE", however there is no error running the query.
So my question is: am I doing something "wrong" even though my query still works? Assuming the initial "USE MYDATABASE1" is necessary, what is the correct way to switch databases while still having #TEMP_TABLE available as a valid object name? (Note that moving the definition of #TEMP_TABLE to after "USE MYDATABASE2" would just shift the problem to #SOME_EARLIER_TEMP_TABLE.)
In SQL USE basically tells the query which database is the "default" database.
Temp tables can play tricks on intellisense - unless they're explicitly defined using the CREATE TABLE #MyTempTable route, intellisense doesn't really know what to do with them a lot of the time. Don't worry though - temp tables are scoped to the query.
Although I do feel it's worth pointing out: while UDTs are database specific, you can create an assembly to use across databases
SELECT * INTO NMANDEV.EMANADM.UCFM_JOB_INSTANCE_DATA_LOG
FROM NMANSTG.EMANADM.UCFM_JOB_INSTANCE_DATA_LOG
Who knows ... what do you want to do, exactly? Looks like you're trying to "copy" data from one table to another. If that's so, then you'd
INSERT INTO NMANDEV.EMANADM.UCFM_JOB_INSTANCE_DATA_LOG
SELECT *
FROM NMANSTG.EMANADM.UCFM_JOB_INSTANCE_DATA_LOG
However, that's wrong as well because what are NMANDEV, EMANADM and NMANSTG? UCFM_JOB_INSTANCE_DATA_LOG seems to be a table name.
Generally speaking, if tables belong to different users in the same database, you'd just precede table names with their owners, e.g.
insert into NMANDEV.UCFM_JOB_INSTANCE_DATA_LOG
select * from NMANSTG.UCFM_JOB_INSTANCE_DATA_LOG
(where NMANDEV is one user, while NMANSTG is another).
first off, noob alert! :))
I need to construct a query that runs on many tables. The tables vary on name just on the last digits as per client code. The thing is, the values that change aren't sequential so looping as in i=1,2,3,... does not work. A possible solution would be to have those values on a given field on an other table.
Here is the code for the first two clients 015 and 061. The leading zero(s) must are essential.
SELECT LnMov2017015.CConta, RsMov2017015.DR, RsMov2017015.NInt, "015" AS CodCli
FROM LnMov2017015 INNER JOIN RsMov2017015 ON LnMov2017015.NReg = RsMov2017015.NReg
WHERE (((LnMov2017015.CConta)="6" And (LnMov2017015.CConta)="7") AND ((RsMov2017015.DR)=9999))
UNION SELECT LnMov2017061.CConta, RsMov2017061.DR, RsMov2017061.NInt, "061" AS CodCli
FROM LnMov2017061 INNER JOIN RsMov2017061 ON LnMov2017061.NReg = RsMov2017061.NReg
WHERE (((LnMov2017061.CConta)="6" And (LnMov2017061.CConta)="7") AND ((RsMov2017061.DR)=9999))
...
So for the first SELECT the table Name is LnMov2017015, the ending 015 being the value, the client code, that changes from table to table e.g. in the second SELECT the table name is LnMov2017061 (061) being what distinguishes the table.
For each client code there are two tables e.g. LnMov2017015 and RsMov2017015 (LnMov2017061 and RsMov2017061 for the second set client shown).
Is there a way that I can build the SQL, based upon the example SQL above?
Does anyone have an idea for a solution? :)
Apparently it is possible to build a query object to read data in another db without establishing table link. Just tested and to my surprise it works. Example:
SELECT * FROM [SoilsAgg] IN "C:\Users\Owner\June\DOT\Lab\Editing\ConstructionData.accdb";
I was already using this structure in VBA to execute DELETE and UPDATE action statements.
Solution found :)
Thank you all for your input.
Instead of linking 100 tables (password protected), I'll access them with SLQ
FROM Table2 IN '' ';database=C:\db\db2.mdb;PWD=mypwd'
And merge them all with a query, before any other thing!
Is there any possibility to write delete query inside Where clause.
Example:
Select ID,Name From MyTable Where ID IN(Delete From MyTable)
It may be crazy, but let me explain my situation. In our reporting tool, we are supporting to enter SQL where query.
We will use our own Select and From Clause query and combine the user's where query input.
Example:
Select ID,Name From MyTable Where ("Query typed by user")
Here, user can type any kind of where query filter..
If he types like ID=100 our final query becomes like this
Select ID,Name From MyTable Where (ID=100)
One of our customer asked us what will happen if anyone type the delete query as where query filter. he feels this may be the security hole..so we have tried that kind of possibility in our dev environment. But the sql returns error for the following query.
Select ID,Name From MyTable Where ID IN(Delete From MyTable)
So finally, my question is, is there any other possibility to write Delete Query inside Where clause or Select clause.. If it possible, how can I restrict it?
Yes. They can run a delete. They can type:
1 = 1; DELETE FROM MY_TABLE;
Or even worse in some ways, (since you should have backups):
1 = 0 UNION SELECT SOCIAL_SECURITY_NUMBER, CREDIT_CARD_NUMBER, OTHER_SENSITIVE_DATA FROM MY_SENSITIVE_TABLE;
Now, in your case its hard to validate. Normally if you are just passing a value to filter on you can use parameterised sql to save yourself. You however also need to let the user select a column. In cases like these, usually we use a drop down to allow the user to select a predefined list of columns and then validate the column name server side. We give the user a text box to enter the value to match and then parameterise that.
It's not quite possible. But he can do something like this :
Select ID,Name From MyTable Where (ID=100); (DELETE FROM MyTable Where 1 = 1)
by using ID=100); (DELETE FROM MyTable Where 1 = 1 instead of ID=100
I believe what your customer is talking about is SQL injection, as long as you have taken appropriate methods to block other queries from running after your select statement is done, then you should have no problem in letting them type whatever it is that you want.
From my experience there is no way to delete anything when you are doing a select statement.
Just make sure you have query terminator characters so they don't write something like the following.
select column1,column2, from myTable where ID in (1,2); delete from my table
this would be a valid worry from your customer if you aren't taking proper steps to prevent sql injection from happening.
You could have your SQL reporting tool just not have update, or delete permission and just have it have Read permission. However, it is up to you guys have you handle your sql injection security.
I am trying to import a large CSV file into a MySQL database. I have loaded the entire file into one flat table. i can select the data that needs to go into separate tables using select statements, my question is how do i copy the results of those select queries to different tables. i would prefer to do it completely in SQL and not have to worry about using a scripting language.
INSERT
INTO new_table_1
SELECT *
FROM existing_table
WHERE condition_for_table_1;
INSERT
INTO new_table_2
SELECT *
FROM existing_table
WHERE condition_for_table_2;
INSERT INTO anothertable (list, of , column, names, to, give, values, for)
SELECT list, of, column, names, of, compatible, column, types
FROM bigimportedtable
WHERE possibly you want a predicate or maybe not;
The answer from Quassnoi was the one I was looking for. Please observe that if new_table_1 doesn't exist yet the "INSERT INTO" statement has to be replaced with a "CREATE TABLE" statement.