I've started to try and write some VBA to execute some queries and I've got stuck at the first hurdle. This is giving an error 3078 which apparently means it can't find the table or query. The table definitely exists and is spelt properly. Indeed the SQL runs fine - I tested it. What am I doing wrong?
Public Function Tester()
str_tbl = "tblGames_atp"
str_mkvrec = "SELECT * FROM " & str_tbl
dbl_fs_pct = DSum("FS", str_mkvrec)
End Function
Cannot reference SQL statement in domain aggregate function, not even a variable set to that statement. Must reference table or query object name. Could reference variable with name string but variable not really needed in this code. If you want function to return a value to calling source, then need to set function value.
Public Function Tester()
Tester = DSum("FS", "tblGames_atp")
End Function
Related
Using the example from the Spring docs, I'm trying to return a value from a mySQL function. I keep getting the error Can't set IN parameter for return value of stored function call;.
I created a mySQL function that works fine (ran in MySQL Workbench). I've written a SimpleJdbcCall statement, set up the parameters as per Spring docs example but consistently get this error. If I turn the function into a procedure, the code works, I just have to retrieve the return value from the result set.
I used https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch13s05.html, section 13.5.8 as reference.
CREATE FUNCTION `ScenarioRegistration`(
environment VARCHAR(45),
username VARCHAR(15),
scenario_name VARCHAR(45)) RETURNS int(11)
A couple of SELECT statements followed by an INSERT then
RETURN scenario_id; // The inserted id
Java code:
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(getJdbcTemplate())
.withFunctionName("ScenarioRegistration")
.withoutProcedureColumnMetaDataAccess();
simpleJdbcCall.addDeclaredParameter(new SqlParameter("environment"
,Types.VARCHAR));
simpleJdbcCall.addDeclaredParameter(new SqlParameter("username"
,Types.VARCHAR));
simpleJdbcCall.addDeclaredParameter(new SqlParameter("scenario_name"
,Types.VARCHAR));
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("environment", environment)
.addValue("username", username)
.addValue("scenario_name", scenario);
simpleJdbcCall.setReturnValueRequired(true);
Integer scenario_id = simpleJdbcCall.executeFunction(
Integer.class, parameters);
All I want the routine to do is give me back the id of the newly inserted scenario.
What I get is:
SQL [{? = call scenarioregistration(?, ?)}]; Can't set IN parameter for return value of stored function call.
I find it interesting that it's taken my THREE input values and changed them to an output and TWO input values.
Anyone enlighten me as to the problem and how to fix it?
Thanks,
Steven.
I would refer to the latest docs here for your answer. It appears Spring is trying to infer the output because you didn't explicity specify one.
Per the docs above there are two valid approaches on calling the desired function with the SimpleJdbcCall:
Inferred Parameters
Because you've specified withoutProcedureColumnMetaDataAccess, Spring isn't going to look and see what the ins/outs are to your function. If you want it easy, just don't specify that and you should be able to do:
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("environment", environment)
.addValue("username", username)
.addValue("scenario_name", scenario);
Integer scenarioId = new SimpleJdbcCall(getJdbcTemplate())
.withFunctionName("ScenarioRegistration")
.executeFunction(Integer.class, parameters);
Explicit Parameters
If you want to keep withoutProcedureColumnMetaDataAccess turned off for whatever reason, you can do:
Integer scenarioId = new SimpleJdbcCall(getJdbcTemplate)
.withFunctionName("ScenarioRegistration")
.withoutProcedureColumnMetaDataAccess()
.useInParameterNames("environment", "username", "scenario_name")
.declareParameters(
new SqlOutParameter("scenario_id", Types.NUMERIC),
new SqlParameter("environment", Types.VARCHAR),
new SqlParameter("username", Types.VARCHAR),
new SqlParameter("scenario_name", Types.VARCHAR)
).executeFunction(Integer.class, parameters);
Note: It appears that order is critical in this example. The output parameter should be declared first, and the subsequent named IN parameters come last. That is, the order of the parameters ? are ordinal in [{? = call scenarioregistration(?, ?, ?)}])
Alternative NamedParameterJdbcTemplate Solution
Another way to invoke your function is via an actual JDBC call. This could hypothetically save you the grief of using the fine tuning of the SimpleJdbcCall.
Integer scenarioId = namedParameterJdbcTemplate.queryForObject(
"SELECT ScenarioRegistration(:environment, :username, :scenario_name)",
parameters,
Integer.class);
I need to call a stored procedure in a MySQL (5.7) database from a VB.NET application. Said procedure makes a SELECT statement at the end which I need to retrieve in my app as a DataSet. Previously it worked fine, but I added an output parameter to the stored procedure, and I get the following error when I call it:
{"Incorrect number of arguments for PROCEDURE my_database.SP_MY_PROCEDURE; expected 3, got
2"}
Here's my current VB.NET code:
Public Shared Function CallStoredProcedure(ByVal stringParam As String,
ByVal intParam As Integer) As DataSet
Try
Dim ds As New DataSet
Dim params As New List(Of MySqlParameter)
Dim arrayParams() As MySqlParameter
params.Add(New MySqlParameter("#param1", stringParam))
params.Add(New MySqlParameter("#param2", intParam))
arrayParams = params.ToArray()
ds = MySqlHelper.ExecuteDataset(connString,
"CALL SP_MY_PROCEDURE(#param1, #param2);",
arrayParams)
Return ds
Catch objException As Exception
Return Nothing
End Try
End Function
I tried adding a third parameter to the CALL statement in the string, like this:
ds = MySqlHelper.ExecuteDataset(connString,
"CALL SP_MY_PROCEDURE(#param1, #param2, param3);",
arrayParams)
but that just returns a different error:
{"OUT or INOUT argument 3 for routine gw_my_database.SP_MY_PROCEDURE
is not a variable or NEW pseudo-variable in BEFORE trigger"}
How can I accomplish this? Maybe ExecuteDataset can't be used with output parameters; at least I haven't found examples or anything. It that's the case, what's a good alternative?
You can definitely use ExecuteDataset() with output parameter. You need to make sure all the mandatory parameters are added to your parameter list including output parameter. You need to confirm the type and size where applicable and set the direction of each parameter correctly. After executing ExecuteDataset() you can retrieve the value from our output parameter.
I could not see adding the third parameter in your code (or perhaps you haven't showed that part), setting direction/type/size.
I am trying to write a function in a module that we take a field from a MS ACCESS query that is passed to it and return the values of the field to another field in the Query.
The code that I have written in the module is provided below.
Public Function YearAmps(ByRef array1() As Double)
Dim array2(0 To UBound(array1())) As Double
Dim I
For I = 0 To UBound(array2())
array2(I) = array1(I)
Next I
YearAmps = array2
End Function
When I put the following in the Query field: YearAmps([SN]), where YearAmps is the function that I am calling and SN is the field that I am passing to the function and run the code, I get an error.
Does anyone know where I am going wrong. Is is possible to pass a field from an Query as an array in a Module and then return that array?
Any help would be greatly appreciated.
I am trying to create a custom function by referencing the Excel Object Model. By first going to Create/Module/Tools/References/ and selecting Microsoft Excel 15.0 Object Library (Access 2010) I was able to allow Access to bring-in the Excel Object Model. From there, I created a basic function in Acces using the Excel functions ACOS and COS. I was then able to run this function in my Query without issue. Here is the function:
Public Function myTestFunction(x As Double) As Double
myTestFunction = Excel.WorksheetFunction.Acos(Cos(50))
End Function
This test function is generally meaningless to me, but was a good first step in achieving my ultimate goal. The next step was to reference a column in my Query within the function itself. Basically, I want to replace the 50 value with each row in my Query column [LAT]. Here is what I've tested:
Public Function myTestFunction(x As Double) As Double
myTestFunction = Excel.WorksheetFunction.Acos(Cos([Queries].[Data Query]![LAT]))
End Function
After attempting to run this function in my Query I receive the following error:
Run-Time Error 424
Object Required
My question is, how can I reference the Query column [LAT] within my function?
Revise your function to operate on its x argument.
Public Function myTestFunction(x As Double) As Double
'myTestFunction = Excel.WorksheetFunction.Acos(Cos(50))
myTestFunction = Excel.WorksheetFunction.Acos(Cos(x))
End Function
Then you can use the function in a query and give it your [LAT] field value.
SELECT dq.[LAT], myTestFunction(dq.[LAT])
FROM [Data Query] AS dq;
I've been looking everywhere for a way of accessing a table's description (same one that appears when you right click a table>table properties) through a SELECT query.
I tried using MSysObjects but I can only retrieve the name of the table using that.
Is it possible to do this through a query or is VBA needed?
As Remou says, you can't get it from a query (but you can include a function that returns it in a query). Here's another function:
Public Function GetTableDescr(stTableName As String) As String
On Error Resume Next
GetTableDescr = CurrentDb.TableDefs(stTableName).Properties("Description").Value
End Function
Here's a query that returns all the non-system tables, with their dates and descriptions (using the function above):
SELECT MSysObjects.Name, msysobjects.datecreate, msysobjects.dateupdate, GetTableDescr([Name]) AS Description
FROM MSysObjects
WHERE (((MSysObjects.Name) Not Like "~*") AND((MSysObjects.Name) Not Like "MSys*") and ((MSysObjects.Type)=1));
Finally, you can do an almost identical function for queries. The trick I found is that you only return non-inherited descriptions, otherwise if a query has no description you get the description of the queried object:
Public Function GetQueryDescr(stQryName As String) As String
On Error Resume Next
If CurrentDb.QueryDefs(stQryName).Properties("Description").Inherited = False Then
GetQueryDescr = CurrentDb.QueryDefs(stQryName).Properties("Description").Value
End If
End Function
The On Error Resume Next is necessary, because until the object has a description the property is null.
You can get the description from the table schema or from TableDef properties, but I do not think a standard query will work.
Set rs = CurrentProject.Connection.OpenSchema(adSchemaTables, _
Array(Empty, Empty, "Rules", Empty))
Debug.Print rs!Description
Using GetQueryDescr() above, you can run this query against the hidden sys table
SELECT MSysObjects.Name, GetQueryDescr([Name]) AS Properties, MSysObjects.DateCreate, MSysObjects.DateUpdate
FROM MSysObjects
WHERE (((MSysObjects.Name) Not Like "~sq_*") AND ((MSysObjects.Type)=5));
type 5 is for queries