Is there a limitation of how many columns can be brought over in one sqlcommand in VBA code? My code is quite long but is used to ensure that I am pulling from the right database at all times. The m2mdata02 will be replaced with code CatalogM2M upon a user's selection in the database. The total number of columns to bring over is 23 columns from 7 tables.
Sqlcommand = “select left(m2mdata02.dbo.jomast.fjobno,5) as job, m2mdata02.dbo.jomast.fjobno, m2mdata02.dbo.jomast.fpartno, m2mdata02.dbo.jomast.fstatus, m2mdata02.dbo.jomast.fact_rel, m2mdata02.dbo.jomast.fddue_date, m2mdata02.dbo.jomast.fprodcl, m2mdata02.dbo.jomast.frel_dt, m2mdata02.dbo.jomast.frouting, m2mdata02.dbo.inmastx.fpartno, m2mdata02.dbo.inmastx.fdescript, m2mdata02.dbo.inmastx.fprice, m2mdata02.dbo.somast.fsono, m2mdata02.dbo.somast.fcompany, m2mdata02.dbo.somast.fcustpono, m2mdata02.dbo.aritem.fcinvoice, m2mdata02.dbo.aritem.fprice, m2mdata02.dbo.aritem.fcsono, m2mdata02.dbo.armast.fcinvoice, m2mdata02.dbo.armast.finvdate, m2mdata02.dbo.shmast.fshipdate, m2mdata02.dbo.shmast.fshipno, m2mdata02.dbo.shmast.fcsono
from m2mdata02.dbo.jomast
left join m2mdata02.dbo.inmastx on m2mdata02.dbo.inmastx.fpartno = m2mdata02.dbo.jomast.fpartno
left join m2mdata02.dbo.somast on m2mdata02.dbo.somast.fsono = m2mdata02.dbo.jomast.fsono
left join m2mdata02.dbo.aritem on m2mdata02.dbo.aritem.FCSONO = m2mdata02.dbo.jomast.fsono
left join m2mdata02.dbo.armast on m2mdata02.dbo.armast.fcinvoice = m2mdata02.dbo.aritem.fcinvoice
left join m2mdata02.dbo.shmast on m2mdata02.dbo.shmast.fcsono = m2mdata02.dbo.somast.fsono
where m2mdata02.dbo.jomast.fprodcl = 'FG11' order by m2mdata02.dbo.jomast.fjobno”
According to MSDN docs, the character limit of String type in VBA is approximately two billion (2^31) Unicode characters. Your SQL query is no where near that limitation. And if using ADO to connect Excel VBA to database, the server engine here being SQL Server decides column limitation and 23 is again no where near maximum capacity.
However, consider using table aliases to cut down on characters, avoid repeating triple period identifiers, and overall improve readability even maintainability as you can adjust table reference easier for each user selection.
select left(j.fjobno,5) as job
, j.fjobno
, j.fpartno
, j.fstatus
, j.fact_rel
, j.fddue_date
, j.fprodcl
, j.frel_dt
, j.frouting
, i.fpartno
, i.fdescript
, i.fprice
, so.fsono
, so.fcompany
, so.fcustpono
, ari.fcinvoice
, ari.fprice
, ari.fcsono
, arm..fcinvoice
, arm..finvdate
, sh.fshipdate
, sh.fshipno
, sh.fcsono
from m2mdata02.dbo.jomast j
left join m2mdata02.dbo.inmastx i on i.fpartno = j.fpartno
left join m2mdata02.dbo.somast so on so.fsono = j.fsono
left join m2mdata02.dbo.aritem ari on ari.FCSONO = j.fsono
left join m2mdata02.dbo.armast arm on arm..fcinvoice = ari.fcinvoice
left join m2mdata02.dbo.shmast sh on sh.fcsono = so.fsono
where j.fprodcl = 'FG11'
order by j.fjobno
By the way, for very long queries, avoid the need to build string in VBA with line concatenation and double quotes, and read directly from a formatted SQL text file:
Dim strSQL As String
' READ SQL QUERY FROM FILE
With CreateObject("Scripting.FileSystemObject")
strSQL = .OpenTextFile("C:\path\to\my\SQL\Query.sql", 1).readall
End With
' REPLACE DB IN STRING
strSQL = Replace(strSQL, "m2mdata02", "someotherdb")
Related
I build a query with this syntax:
SELECT e.codigo AS `Código`,
e.razao_social AS `Razão Social`,
e.grupo AS `Grupo`,
e.tributacao AS `Tributação`,
e.sistema AS `Sistema`,
r.nome AS `Responsável`,
date_format(t.competencia, '%m/%Y') AS `Competência`,
s.nome AS `Status`,
c.nome AS `Tipo Conferência`
FROM tarefa AS t
RIGHT JOIN empresa AS e ON t.id_empresa = e.id_empresa
LEFT JOIN responsavel AS r ON t.id_responsavel = r.id_responsavel
LEFT JOIN status AS s ON t.id_status = s.id_status
LEFT JOIN conferencia AS c ON t.id_conferencia = c.id_conferencia
WHERE c.nome = 'Encerramento Contábil'
ORDER BY `Competencia`;
I did a test query in MariaDB, and it worked.
Now, i am use this query in Access with VBA MSExcel, where it has the same structure and relationship between tables, but return error.
message error vba:
Syntax error (missing operator) in expression 't.id_empresa =
e.id_empresa LEFT JOIN responsavel AS r ON t.id_respons'
This is my code vba MSExcel:
Sub testSql()
'Creating objects of Connection and Recordset
Dim conn As New Connection, rec As New Recordset
Dim DBPATH, PRVD, connString, query As String
'Declaring fully qualified name of database. Change it with your database's location and name.
DBPATH = "C:\Users\ctb06\Documents\Database2.accdb"
'This is the connection provider. Remember this for your interview.
PRVD = "Microsoft.ace.OLEDB.12.0;"
'This is the connection string that you will require when opening the the connection.
connString = "Provider=" & PRVD & "Data Source=" & DBPATH
'opening the connection
conn.Open connString
'the query I want to run on the database.
query = "SELECT e.codigo AS `Código`, e.razao_social AS `Razão Social`, e.grupo AS `Grupo`, e.tributacao AS `Tributação`, e.sistema AS `Sistema`, r.nome AS `Responsável`, date_format(t.competencia, '%m/%Y') AS `Competência` FROM tarefa AS t RIGHT JOIN empresa AS e ON t.id_empresa = e.id_empresa LEFT JOIN responsavel AS r ON t.id_responsavel = r.id_responsavel;"
'running the query on the open connection. It will get all the data in the rec object.
rec.Open query, conn
'clearing the content of the cells
Range("a1").Select
Cells.ClearContents
If (rec.RecordCount <> 0) Then
col = 1
For Each resp In rec.Fields
With Cells(1, col)
.Value = resp.Name
End With
col = col + 1
Next resp
Cells(2, 1).CopyFromRecordset rec
End If
rec.Close
conn.Close
End Sub
Where am I missing?
No two SQL dialects are exactly the same for exact transferability. Simply, MariaDB's SQL will not perfectly align to MS Access' SQL similar to running same query from Oracle to Postgres, MySQL to SQL Server, Sybase to DB2... There will need to be some translation.
Specifically:
DATE_FORMAT is not an available function in MS Access. Instead use FORMAT with appropriate format pattern which does not use %.
More than one JOIN require parentheses wrapping in MS Access. However, your mix of RIGHT JOIN and LEFT JOIN may require nested joining.
(Admittedly, this is a frustrating requirement for new Access users to build complex queries with Query Designer and not SQL. I raised this suggested change among others to Access' SQL dialect.)
Fortunately, backticks are supported in MS Access though square brackets, [...], are the more popular form to escape identifiers with special characters or keywords.
Consider following adjustment:
SELECT e.codigo AS `Código`,
e.razao_social AS `Razão Social`,
e.grupo AS `Grupo`,
e.tributacao AS `Tributação`,
e.sistema AS `Sistema`,
r.nome AS `Responsável`,
FORMAT(t.competencia, 'mm/yyyy') AS `Competência`,
s.nome AS `Status`,
c.nome AS `Tipo Conferência`
FROM ((((empresa AS e
RIGHT JOIN tarefa AS t ON t.id_empresa = e.id_empresa)
LEFT JOIN responsavel AS r ON t.id_responsavel = r.id_responsavel)
LEFT JOIN status AS s ON t.id_status = s.id_status)
LEFT JOIN conferencia AS c ON t.id_conferencia = c.id_conferencia)
WHERE c.nome = 'Encerramento Contábil'
ORDER BY `Competencia`;
I have been trying to create a form which contains information from 3 tables. On this form I would like to have a filter combo box so that the user may select a member type and it will filter the list to members with that member type.
Members in our database can have more than one type. For this reason I created a memberTable:
MemberID
FName
SName
etc.
A membertype table:
MemberTypeID
MemberTypeName
and a joining table membermembertype:
MemberID
MemberTypeID
I have tried to set my form up with a number of different queries:
SELECT qryMemberType.MemberID, qryMemberType.FName, qryMemberType.SName,
qryMemberType.MemberTypeName, qryMemberType.MemberTypeID FROM qryMemberType;
SELECT [member].[MemberID] AS [member_MemberID], [member].[FName], [member].[SName],
[membertype].[MemberTypeID] AS [membertype_MemberTypeID], [membertype].[MemberTypeName],
[membermembertype].[MemberID] AS [membermembertype_MemberID], [membermembertype].[MemberTypeID]
SELECT [member].[MemberID] AS [member_MemberID], [member].[FName], [member].[SName],
[membermembertype].[MemberID] AS [membermembertype_MemberID],
[membermembertype].[MemberTypeID] AS [membermembertype_MemberTypeID],
[membertype].[MemberTypeID] AS [membertype_MemberTypeID]
The VBA for the combo box that I have been attempting to filter with is:
Dim myMember As String
myMember = "SELECT ... FROM ... WHERE ([MemberTypeID] = " & Me.cboMemberType & ");"
Me.frmFilterTestSub.Form.RecordSource = myMember
Me.frmFilterTestSub.Form.Requery
I have tried numerous different syntaxes for the SELECT statement in the VBA for the combo box including:
"Select * from membermembertype where ([MemberTypeID] = " & Me.cboMemberType & ")"
"SELECT member.MemberID AS member_memberID, member.FName, member.SName,
membertype.MemberTypeID AS membertype_MemberTypeID, membertype.MemberTypeName,
membermembertype.MemberID AS membermembertype_MemberID,
membermembertype.MemberTypeID AS membermembertype_MemberTypeID
FROM member
LEFT JOIN (membertype
RIGHT JOIN membermembertype ON membertype.[MemberTypeID] = membermembertype.[MemberTypeID])
ON member.[MemberID] = membermembertype.[MemberID]
WHERE ([MemberTypeID] = " & Me.cboMemberType & ")"
"SELECT member.*,
(membermembertype.MemberID AS mmt_MemberID),
(membermembertype.MemberTypeID AS mmt_MemberTypeID),
membertype.MemberTypeName
FROM (member
LEFT JOIN membermembertype ON mmt_MemberID = (member.MemberID AS m_MemberID))
RIGHT JOIN membertype ON mmt_MemberTypeID=(membertype.MemberTypeID AS mt_MemberTypeID)
WHERE ([MemberTypeID] = " & Me.cboMemberType & ");"
I'm pretty sure the first example returned the closest result with the list returning the correct number of records for each member type selected, however the fields were filled with the #Name? error value which is why I was trying to do a number of different ways to join the tables. The other SELECT STATEMENTS are returning SQL Syntax errors.
Any advice would be greatly appreciated!
Since you only want to list the members, I guess that you are not really interested with membertype table info, then you can simply do this :
"SELECT member.MemberID AS member_memberID, member.FName, member.SName
FROM member
INNER JOIN membermembertype
ON (membermembertype.[MemberTypeID] = " & Me.cboMemberType & " AND member.[MemberID]=membermembertype.[MemberID]) "
Right outer join is highly frowned on in SQL, when you can use a left outer join in the correct order instead.
In your case, inner joins are better anyway.
You should use a parameter rather than string concatenation if you care about security, but since you're using Access I guess anyone with access to the file can already do what they like.
Please try this one and let me know if you get an error.
SELECT [Member].MemberId
, [Member].FName
, [Member].SName
, [MemberType].MemberTypeId
, [MemberType].MemberTypeName
FROM ((MemberType
INNER JOIN MemberMemberType ON MemberMemberType.MemberTypeId = MemberType.MemberTypeId)
INNER JOIN Member ON Member.MemberId = MemberMemberType.MemberId)
WHERE MemberType.MemberTypeId = 123 --Put your parameter here once you've tested that it works for a specific value
I'm a long time follower of Stack overflow but this is my first post. I'm hoping the community can help.
I have a successful Access Query that returns the required results - Perfect!
HOWEVER, I'm trying to return the same using OLEDB connection to the database within an ASP script. This is all legacy stuff however we are allowing web access to this legacy information.
MS Access (2016) shows Query as this... (works)
SELECT [EventName] & ": " & [RoundCaption] AS RoundTitle, ChunkEntryTable.WinPos
FROM ((EventTable INNER JOIN EventRoundTable ON EventTable.EventId = EventRoundTable.EventId) INNER JOIN ((RoundHeatTable INNER JOIN ChunkTable ON RoundHeatTable.RoundHeatId = ChunkTable.RoundHeatId) INNER JOIN (EventEntryTable INNER JOIN ChunkEntryTable ON EventEntryTable.EventEntryId = ChunkEntryTable.EventEntryId) ON ChunkTable.ChunkId = ChunkEntryTable.ChunkId) ON EventRoundTable.RoundKeyId = RoundHeatTable.RoundKeyId) LEFT JOIN EventEntryMemberTable ON EventEntryTable.EventEntryId = EventEntryMemberTable.EventEntryId
WHERE (((EventEntryTable.Entry1Id)=[EntryId])) OR (((EventEntryTable.Entry2Id)=[EntryId])) OR (((EventEntryTable.Entry3Id)=[EntryId])) OR (((EventEntryMemberTable.MemberId)=[EntryId]))
ORDER BY EventTable.SortIdx, EventRoundTable.RoundId DESC , EventRoundTable.IsRepechage DESC;
Doing this in OLEDB. Connection string as follows...
<%
' FileName="Connection_ado_conn_string.htm"
' Type="ADO"
' DesigntimeType="ADO"
' HTTP="true"
' Catalog=""
' Schema=""
Dim MM_csresultdb_STRING
MM_csresultdb_STRING = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=xyz.mde;Jet OLEDB:Database Password=xxxxxxxxx;"
%>
Connection works perfectly but I can't seem to get the SQL command to work. I get "No value given for one or more required parameters".
NOTE: I have replaced [EntryID] in 4 places with a valid value and it works perfectly in Access just not outside of Access using OLEDB. Here's what the SQL is I'm using...
SELECT EventTable.EventName & ": " & EventRoundTable.RoundCaption AS RoundTitle, ChunkEntryTable.WinPos FROM
((EventTable INNER JOIN EventRoundTable ON EventTable.EventId = EventRoundTable.EventId) INNER JOIN
((RoundHeatTable INNER JOIN ChunkTable ON RoundHeatTable.RoundHeatId = ChunkTable.RoundHeatId) INNER JOIN
(EventEntryTable INNER JOIN ChunkEntryTable ON EventEntryTable.EventEntryId = ChunkEntryTable.EventEntryId) ON ChunkTable.ChunkId = ChunkEntryTable.ChunkId) ON ChunkTable.ChunkId = ChunkEntryTable.ChunkId)
ON EventRoundTable.RoundKeyId = RoundHeatTable.RoundKeyId)
WHERE ((EventEntryTable.Entry1Id)=4741) OR ((EventEntryTable.Entry2Id)=4741) OR ((EventEntryTable.Entry3Id)=4741)
ORDER BY EventTable.SortIdx, EventRoundTable.RoundId DESC , EventRoundTable.IsRepechage DESC;
FOUND PROBLEM ** See answer below
FOUND PROBLEM ** It's to do with this part of the SQL...
[EventName] & ": " & [RoundCaption] AS RoundTitle
Changed to
[EventName], [RoundCaption] AS RoundTitle
and it works but gives me two separate fields rather than the one concatenated field called "RoundTitle". So I'll join the two result fields during the display output rather than at the query stage.
Whew! That many days to figure out. Thanks to the comments that kinda steered me in that direction of the AS part of the statement.
this Statement works totaly fine in ORACLE SQL DEVELOPER, but when I insert it to my vba makro it won't return me my BLOB files from the database. The statement worked before in VBA with a data-number variable instead of referencing to SYSDATE...
Provider is OraOLEDB.Oracle, the Connections string "works/opens" but there is no data to pass my - IF rs.EOF = FALSE Then - I've already tested eof=true but no data comes through....Any ideas ? thx!
select datas
from tdb
INNER JOIN (select datas_id
from tfdz
INNER JOIN (select fb_id
from tfb
INNER JOIN (select pu_id
from tpu
INNER JOIN (select tap.p_id
from tap
INNER JOIN (SELECT po_id
FROM tpo
WHERE tpo.lastdate like (SYSDATE-1)
) sub_tpo
ON tap.po_id = sub_tpo.po_id and tap.lastdate like (SYSDATE-1)
) sub_tap
ON tpu.p_id = sub_tap.p_id
) sub_tpu
ON tfb.pu_id = sub_tpu.pu_id
where tfb.deleated = 0
) sub_tfb
ON tfdz.fb_id = sub_tfb.fb_id
) sub_tfdz
ON tdb.datas_id = sub_tfdz.datas_id
order by sub_tfdz.datas_id asc
It would be good to see how you are passing it, I assume as a string, have you tried.
WHERE tpo.lastdate like (" & Format(DateAdd("d", -1, Now()), "DD/MMM/YYYY") & ")"
You may need to change the format to be compatible Oracle date processing
I need a little help developing my SQL query. My goal is to remove an entry. My condition is two tables away. I've gotten this far but I can't seem to find where the other mistake
con.Execute "DELETE FROM Expenses INNER JOIN Agreements ON Agreements.AgreementsID =
Expenses.AgreementID AND INNER JOIN Audits
ON Audits.AuditID = Agreements.AuditID WHERE Audits.Share = True"
I'm using access 2007 and my con variable is
con.Open _
"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" & _
"Dbq=" & Loc & ";"
Try This, You are using AND before INNER JOIN, remove that only.
DELETE DISTINCTROW Expenses.*
FROM Expenses
INNER JOIN Agreements ON Agreements.AgreementsID = Expenses.AgreementID
INNER JOIN Audits ON Audits.AuditID = Agreements.AuditID
WHERE Audits.Share = True
[EDIT Query]
DELETE Expenses.*
FROM Expenses
WHERE Expenses.AgreementID IN (
SELECT Agreements.AgreementID FROM Agreements
INNER JOIN Audits ON Audits.AuditID = Agreements.AuditID
WHERE Audits.Share = True
)
OP get error:- Too few parameters Expected 2.
To handle this, This error may be obtained because the any column names being selected have special characters in it. If there are special characters in the column names of the database, the name should be surrounded with brackets in the SQL query. So if you have any column name which have special char value , then try [ColumnName]