i type a query for my filter, the query needs to join 2 or 3 tables in order for me to do my filter. when i try to use inner join i got a inner join not supported error. the database i use is ms.access. I'll provide the table contents in the comments.
i tried this code it works but the assignment require inner join
strSQL = "SELECT m.primaryTitle, m.startYear as startYear, m.genres as genres, r.averageRating as Rating FROM basic m, Rating r where m.tconst=r.tconst AND (" & fieldselect & " LIKE '%" & TextBox1.Text & "%')"
Select Case ComboBox1.Text
Case "year"
fieldselect = "startYear"
Case "genre"
fieldselect = "genres"
Case "rating"
fieldselect = "averageRating"
End Select
conn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Movies.accdb; Persist Security Info=False;")
strSQL = "SELECT m.primaryTitle, m.startYear as startYear, m.genres as genres, r.averageRating as Rating FROM basic m INNER join Rating r on m.tconst=r.tconst (" & fieldselect & " LIKE '%" & TextBox1.Text & "%')"
conn.Open()
da = New OleDbDataAdapter(strSQL, conn)
Dim ds As New DataSet("Movies")
da.Fill(ds, "Movies")
DataGridView1.DataSource = ds.Tables("Movies")
conn.Close()
strSQL = "SELECT m.primaryTitle, m.startYear as startYear, m.genres as genres, r.averageRating as Rating FROM basic m, Rating r where m.tconst=r.tconst AND (" & fieldselect & " LIKE '%" & TextBox1.Text & "%')"
the result of this code is not what i expected, when i selected one of the items from the combobox to filter, i got everything display in the datagrid view, but i want to show specific columns or few columns of one table.
Try this one:
Dim da as oledbdataadapter = new oledbdataadapter ("Select column_name from table A inner join table B on A.column_name = B.column_name WHERE column_name = '" & combobox.text & "'",oledbconnection)
dim dt as datatable = new datatable
da.fill(dt)
datagridview.datasource = dt
Related
I have an Arraylist of Dates as such
8/30/2020
8/27/2020
9/28/2020
9/9/2020
8/31/2020
8/29/2020
I then have a query with an in clause for the dates as such
allQuery = "Select pj.ProjectName, tcd.Date, sum(tcd.Executed), sum(tcd.Passed), sum(tcd.Passedbug), sum(tcd.Flaky), sum(tcd.Failed), sum(tcd.Newfailures) "
allQuery &= "From qastats.dbo.TestCaseDetails tcd inner Join qastats.dbo.Pipelines p on tcd.PipelineID=p.PipelineID inner Join qastats.dbo.Projects pj on p.ProjectID=pj.ProjectID "
allQuery &= "where pj.ProjectName =#projectname "
allQuery &= "And tcd.Date in (#dates) group by pj.ProjectName, tcd.Date"
I want to take the list of dates in the Array list and put it in this format (same as String.Join)
8/30/2020,8/27/2020,9/28/2020,9/9/2020,8/31/2020,8/29/2020
so I can pass them in as a value for the parameter
comm.Parameters.Add("#dates", SqlDbType.DateTime).Value = ListofDates
Is there a way to do it the way I want or a better way?
Thanks
As suggested on the comments, use List instead of ArrayList.
Use a table valued parameter for the dates.
You'll need to create the table type in the database like this (I modified your query slightly moving the dates validation into a join if you want it in the where you can uncomment the commented line and comment the one for the join to #dates):
CREATE TYPE dbo.DatetimeTvp AS TABLE
(
value DATETIME NOT NULL
)
And then you can use this code:
Private Sub RunQuery()
Dim dates As IList(Of DateTime) = New List(Of DateTime)({DateTime.Now, DateTime.UtcNow})
Dim sb As StringBuilder = New StringBuilder()
sb.AppendLine(" Select pj.ProjectName, tcd.Date, sum(tcd.Executed), sum(tcd.Passed), sum(tcd.Passedbug), sum(tcd.Flaky), sum(tcd.Failed), sum(tcd.Newfailures) ")
sb.AppendLine(" From qastats.dbo.TestCaseDetails tcd ")
sb.AppendLine(" inner Join qastats.dbo.Pipelines p on tcd.PipelineID=p.PipelineID ")
sb.AppendLine(" inner Join qastats.dbo.Projects pj on p.ProjectID=pj.ProjectID ")
sb.AppendLine(" inner Join #dates dts on dts.value = tcd.Date ")
sb.AppendLine(" where pj.ProjectName =#projectname ")
'sb.AppendLine(" and tcd.Date in (select value from #dates) ")
sb.AppendLine(" group by pj.ProjectName, tcd.Date ")
Using cn As SqlConnection = New SqlConnection(ConnectionString)
Using cmd As SqlCommand = New SqlCommand(sb.ToString(), cn)
Dim pDates = GetTvp("#dates", dates.Distinct())
cmd.Parameters.Add(pDates)
Dim ds As DataSet = New DataSet()
Dim sqlAd = New SqlDataAdapter(cmd)
sqlAd.Fill(ds)
Print(ds)
End Using
End Using
End Sub
Private Function GetTvp(ByVal name As String, ByVal dates As IEnumerable(Of DateTime)) As SqlParameter
Dim dt As DataTable = New DataTable()
dt.Columns.Add("value", GetType(DateTime))
For Each d In dates
dt.Rows.Add(d)
Next
Dim p As SqlParameter = New SqlParameter(name, dt)
p.SqlDbType = SqlDbType.Structured
p.TypeName = "dbo.DatetimeTvp"
Return p
End Function
My query works in VBA code, but I will have a lot of this kind of queries, so I don't want to create a new "rst" section every time. (recordset).
The code I created is below.
Private Sub wpr_krotkaNazwaProjektu_AfterUpdate()
Dim rst4 As DAO.Recordset
Dim rst5 As DAO.Recordset
Dim strSql4 As String
Dim strSql5 As String
Dim krotkaNazwaProjektu4 As String
Dim krotkaNazwaProjektu5 As String
krotkaNazwaProjektu4 = wpr_krotkaNazwaProjektu.Text
krotkaNazwaProjektu5 = wpr_krotkaNazwaProjektu.Text
strSql4 = "SELECT Ewidencje.E_dataRozpoczeciaProjektu from Ewidencje INNER JOIN KP_KartyProjektow on Ewidencje.ID_kartyProjektu = KP_KartyProjektow.ID_kartyProjektu WHERE KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & (krotkaNazwaProjektu4) & "' "
strSql5 = "SELECT Ewidencje.E_dataPlanowaneZakonczenieProjektu from Ewidencje INNER JOIN KP_KartyProjektow on Ewidencje.ID_kartyProjektu = KP_KartyProjektow.ID_kartyProjektu WHERE KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & (krotkaNazwaProjektu5) & "' "
Set rst4 = CurrentDb.OpenRecordset(strSql4)
Set rst5 = CurrentDb.OpenRecordset(strSql5)
przypisanie4 = rst4!E_dataRozpoczeciaProjektu
przypisanie5 = rst5!E_dataPlanowaneZakonczenieProjektu
rst4.Close
Set rst4 = Nothing
rst5.Close
Set rst5 = Nothing
wpr_planowanaDS.Value = przypisanie4
wpr_planowanaDZ.Value = przypisanie5
End Sub
I don't want to open "rst" every time, whether such a query can be modified in such a way that it won't create many variables in ten queries.
I don't know if I understand you correctly.
Using the next code you should be able to do the same just using one variable for each thing:
Private Sub wpr_krotkaNazwaProjektu_AfterUpdate()
Dim rst As DAO.Recordset
Dim strSql As String
Dim krotkaNazwaProjektu As String
krotkaNazwaProjektu = wpr_krotkaNazwaProjektu.Text
strSql = "SELECT Ewidencje.E_dataRozpoczeciaProjektu from Ewidencje INNER JOIN KP_KartyProjektow on Ewidencje.ID_kartyProjektu = KP_KartyProjektow.ID_kartyProjektu WHERE KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & krotkaNazwaProjektu & "' "
Set rst = CurrentDb.OpenRecordset(strSql)
przypisanie = rst!E_dataRozpoczeciaProjektu
rst.Close
wpr_planowanaDS.Value = przypisanie
strSql = "SELECT Ewidencje.E_dataPlanowaneZakonczenieProjektu from Ewidencje INNER JOIN KP_KartyProjektow on Ewidencje.ID_kartyProjektu = KP_KartyProjektow.ID_kartyProjektu WHERE KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & krotkaNazwaProjektu & "' "
Set rst = CurrentDb.OpenRecordset(strSql)
przypisanie = rst!E_dataPlanowaneZakonczenieProjektu
rst.Close
wpr_planowanaDZ.Value = przypisanie
Set rst = Nothing
End Sub
The use of non-English names makes it impossible to figure out what your data is about but you could try something like this:
"SELECT IIF(KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & (krotkaNazwaProjektu4) & "',Ewidencje.E_dataRozpoczeciaProjektu,NULL) AS KP_krotkaNazwaProjektu
IIF(KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & (krotkaNazwaProjektu5) & "',Ewidencje.E_dataPlanowaneZakonczenieProjektu,NULL) AS E_dataPlanowaneZakonczenieProjektu
FROM Ewidencje
INNER JOIN KP_KartyProjektow on Ewidencje.ID_kartyProjektu = KP_KartyProjektow.ID_kartyProjektu
WHERE KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & (krotkaNazwaProjektu4) & "' OR KP_KartyProjektow.KP_krotkaNazwaProjektu = '" & (krotkaNazwaProjektu5) & "'"
It combines your two queries into one. It can probably be simplified quite a bit if I understood what it is about and which field names are unique between the two linked tables and there may be a quote missing here or there that you may have to troubleshoot.
I have a working SQL Query with a CTE and I need that query in my vb.net application, but the problem is I get an error that states:
"Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'"
and the code is like this:
Dim da As New OleDbDataAdapter
Dim ds As New DataSet
Dim dt As New DataTable
Dim sqlcmd As String = (";WITH q AS
(
SELECT a.*
FROM SampleData AS a
WHERE EXISTS (SELECT 1
FROM SampleData AS b
WHERE a.Name = b.Name
AND a.Account= b.Account
AND a.Amount = -b.Amount)
)
DELETE FROM q OUTPUT DELETED.* INTO SampleData2")
If connDB.State = ConnectionState.Closed Then
connDB.Open()
End If
Try
ds.Tables.Add(dt)
da = New OleDbDataAdapter(sqlcmd, connDB)
da.Fill(dt)
Any help on this? I can't find any solution to this.
Here is my function that works with a simple CTE, use this function to test your expression, just replace your CTE in it and see, you might need fix your query.
Public Sub RecursiveData()
Dim connectionString As String = "Initial Catalog=DBName;Data Source=ServerName;uid=user;password=mypassword;Connection Timeout=50000"
Dim cteQuery As String = ";WITH cte " & vbCrLf &
" AS(SELECT 1 AS n " & vbCrLf &
" UNION ALL " & vbCrLf &
" SELECT n + 1 " & vbCrLf &
" FROM cte " & vbCrLf &
" WHERE n <50 " & vbCrLf &
" ) " & vbCrLf &
" SELECT n " & vbCrLf &
" FROM cte where n <= 5; "
Using _con As New SqlConnection(connectionString)
Using _cmd As New SqlCommand(cteQuery, _con)
_con.Open()
Using rdr As SqlDataReader = _cmd.ExecuteReader()
While rdr.Read()
Console.WriteLine(rdr.GetValue(0).ToString())
End While
rdr.Close()
End Using
_con.Close()
End Using
End Using
End Sub
I am trying to connect to SQL Server from Excel VBA using the following code. But when I run the below query, I get an error
Run-time error '-2147217900 (80040e14).
Here is my code:
Dim objMyConn As ADODB.Connection
Dim objMyCmd As ADODB.Command
Dim objMyCmd1 As ADODB.Command
Dim objMyRecordset As ADODB.Recordset
Dim rngUsedRange
Set objMyConn = New ADODB.Connection
Set objMyCmd = New ADODB.Command
Set objMyRecordset = New ADODB.Recordset
Set rngUsedRange = ActiveSheet.UsedRange
'Open Connection'
objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=10.5.3.16;Initial Catalog=PROTELECOM_AMERICAN_TOWERS;Trusted_connection=yes;"
objMyConn.Open
'Set and Excecute SQL Command'
Set objMyCmd.ActiveConnection = objMyConn
objMyCmd.CommandText = ";WITH CTE AS(SELECT BAN.BAN_IDFR, BAN.BAN_NBR, BAN.BAN_STATUS FROM PROTELE_BAN BAN INNER JOIN PROTELE_BILL BILL ON BAN.BAN_IDFR = BILL.BAN_IDFR" & _
"GROUP BY BAN.BAN_IDFR,BAN.BAN_NBR,BAN.BAN_STATUS)SELECT DISTINCT V.ORG_NAME [VENDOR NAME], CTE.BAN_NBR [BAN#], SVR.SER_ACCT_NBR [WTN#],W.COST_CENTER[COST CENTER],W.COST_CODE[COST CODE], BA.ECOM_ID [VENDOR ID],BC.SERVICE_TYPE [SERVICE TYPE], CONVERT(VARCHAR(10),MAX(B.BILL_DATE),101) AS [BILL DATE],SUM(BC.AMOUNT) AMOUNT, B.EXTRACT_STATUS [EXTRACT STATUS],CONVERT(VARCHAR(10),B.EXTRACT_DATE,101) AS [EXTRACTED DATE]" & _
"FROM CTE INNER JOIN PROTELE_BILL B ON CTE.BAN_IDFR = B.BAN_IDFR" & _
"INNER JOIN PROTELE_BILL_CHARGE BC ON B.BILL_IDFR = BC.BILL_IDFR" & _
"INNER JOIN PROTELE_BAN_WTN_MAPPING MAPP ON B.BAN_IDFR = MAPP.BAN_IDFR" & _
"INNER JOIN PROTELE_SVR_WTN SVR ON SVR.SVR_ACCT_IDFR=BC.SVR_ACCT_IDFR" & _
"INNER JOIN PROTELE_SVR_WTN_DETAILS W ON CTE.BAN_IDFR = W.BAN_IDFR AND SVR.SVR_ACCT_IDFR = W.SVR_ACCT_IDFR AND B.BAN_IDFR=W.BAN_IDFR" & _
"INNER JOIN PROTELE_BAN_VENDOR BV ON CTE.BAN_IDFR = BV.BAN_IDFR" & _
"INNER JOIN PROTELE_BAN BA ON CTE.BAN_IDFR = BA.BAN_IDFR" & _
"INNER JOIN PROTELE_LOCATION C ON C.LOCA_IDFR = BV.VNDR_LOCA_IDFR" & _
"INNER JOIN PROTELE_VENDOR V ON C.ORG_IDFR = V.ORG_IDFR WHERE BC.SVR_ACCT_IDFR=W.SVR_ACCT_IDFR AND (B.EXTRACT_DATE BETWEEN '02/05/2016' AND '02/06/2016')" & _
"GROUP BY CTE.BAN_NBR, B.EXTRACT_DATE, BA.ECOM_ID,B.BILL_DATE,B.EXTRACT_STATUS,BC.SERVICE_TYPE,W.COST_CENTER,W.COST_CODE, SVR.SER_ACCT_NBR,V.ORG_NAME" & _
"ORDER BY CTE.BAN_NBR, V.ORG_NAME;"
objMyCmd.CommandType = adCmdText
'Open Recordset'
Set objMyRecordset.Source = objMyCmd
objMyRecordset.Open
For intColIndex = 0 To objMyRecordset.Fields.Count - 1
Selection.Offset(0, intColIndex).Value = objMyRecordset.Fields(intColIndex).Name
Next
'Copy Data to Excel'
ActiveSheet.Range("A2").CopyFromRecordset objMyRecordset
The one thing that jumps to my attention is your concatenations. You don't seem to be padding spaces or return characters between your concats.
For example, when you do this:
sql = "select one, two, three" & _
"from x"
it will render the output as:
select one, two, threefrom x
Which should error.
Can you add spaces at the end of each string and see if that helps? With the exception of that, I don't see any glaring issues with the code.
I want to update TableA with values from TableB on a nightly basis. Right now, I'm trying to do this with SSIS 2005 using a Script Task with the SQL in it. Each time I try to do the update in this manner, I get a time-out error.
Is there a better way to do this in SSIS?
Current information below:
Public Sub Main()
Const Component_Name As String = "Updating TableA Data"
Const Conn_String As String = "Data Source=DB_A;Initial Catalog=TableA;Integrated Security=SSPI;"
Const sql_Emp As String = "Update TableA Set Contract = c.License_No, SEIN = convert(varchar, c.Lic_Exp_Date, 101) " _
& "From Server.DB_B.dbo.TableB c Inner Join TableA b on " _
& "rtrim(ltrim(c.business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14)))) " _
& "Where c.Lic_Exp_Date = (select Max(Lic_Exp_Date) From Server.DB_B.dbo.TableB " _
& "Where rtrim(ltrim(business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))) " _
& "and convert(varchar, c.Lic_Exp_Date, 101) <> convert(varchar, b.SEIN, 101)"
Dim con As SqlConnection = New SqlConnection(Conn_String)
Try
Dts.Log("Opening DB Connection: " & con.ConnectionString, 0, Nothing)
con.Open()
Dim duh As New SqlCommand(sql_Emp, con)
duh.ExecuteNonQuery()
con.Close()
Dts.Log(String.Format(Component_Name), 0, Nothing)
Dts.Events.FireInformation(0, Component_Name, String.Format("TableA Data Updating"), "", 0, True)
Dts.TaskResult = Dts.Results.Success
Catch ex As Exception
Dts.Events.FireError(0, Component_Name, ex.Message, "", 0)
Dts.Log("Exception detected: " & ex.ToString, 0, Nothing)
Dts.TaskResult = Results.Failure
End Try
End Sub
Let's start by cleaning that up a little:
Public Sub Main()
Const Component_Name As String = "Updating TableA Data"
Const Conn_String As String = "Data Source=DB_A;Initial Catalog=TableA;Integrated Security=SSPI;"
Const sql_Emp As String = _
"UPDATE TableA" _
+ " SET Contract = c.License_No, SEIN = convert(varchar, c.Lic_Exp_Date, 101)" _
+ " FROM Server.DB_B.dbo.TableB c" _
+ " INNER JOIN TableA b" _
+ " ON rtrim(ltrim(c.business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))" _
+ " WHERE c.Lic_Exp_Date= (" _
+ " SELECT MAX(Lic_Exp_Date)" _
+ " FROM Server.DB_B.dbo.TableB" _
+ " WHERE rtrim(ltrim(business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))" _
+ ") AND convert(varchar, c.Lic_Exp_Date, 101) <> convert(varchar, b.SEIN, 101)"
Try
Using con As New SqlConnection(Conn_String), _
cmds New SqlCommand(sql_Emp, con)
Dts.Log("Opening DB Connection: " & con.ConnectionString, 0, Nothing)
con.Open()
cmd.ExecuteNonQuery()
Dts.Log(String.Format(Component_Name), 0, Nothing)
Dts.Events.FireInformation(0, Component_Name, String.Format("TableA Data Updating"), "", 0, True)
Dts.TaskResult = Dts.Results.Success
End Using
Catch ex As Exception
Dts.Events.FireError(0, Component_Name, ex.Message, "", 0)
Dts.Log("Exception detected: " & ex.ToString, 0, Nothing)
Dts.TaskResult = Results.Failure
End Try
End Sub
Okay, now that I can read it I can start looking at what might be broken. Check back in a few minutes for edits.
Okay, now let's look at that query. I'm missing some data type information, so I'm going to make some assumptions. Please correct any that are wrong:
b.Account_Key is some number type, probably int. Otherwise you wouldn't need to convert to varchar
The Lic_Exp_Date columns really are of type datetime
If those are correct, I think this will do what you want, but do it a lot faster:
UPDATE TableA
SET Contract = c1.License_No, SEIN = DATEADD(dd,0, DATEDIFF(dd,0, c1.Lic_Exp_Date))
FROM TableA b
INNER JOIN Server.DB_B.dbo.TableB c1
ON ISNUMERIC(c1.busines_lic) = 1 AND cast(c1.business_lic AS int) = b.Account_Key
INNER JOIN
(
SELECT business_lic, MAX(Lic_Exp_Date) AS Lic_Exp_Date
FROM Server.DB_B.dbo.TableB
GROUP BY business_lic, License_No
) c2 ON c2.business_lic = c1.business_lic AND c1.Lic_Exp_Date=c2.Lic_Exp_Date
WHERE DATEADD(dd,0, DATEDIFF(dd,0, c1.Lic_Exp_Date)) <> DATEADD(dd,0, DATEDIFF(dd,0, b.SEIN))
Here's what changed:
Turn the correlated subquery into a join. A join will be much faster, however the query optimizer might have been doing this for you already
Eliminate the need to call a number of per-row functions - should also help you match up with indexes better.
Use an integer comparison rather than string for your main join
Use date functions rather than convert to strings to remove the time portion, which should be much faster and in turn allow me to:
Use date comparisons rather than string comparisons in your join
The better way would be an Execute SQL task.