MS Access Form bound to ADO recordset refresh and filter error - ado

I'm using Access as a front-end to SQL Server and trying to use ADO recordset as a source for Access Form.
I'm able to see records in datasheet view, I can add and edit records on that form.
Now I'm stuck on 2 errors I get when I try to apply text or number filters to ADO recordset bound Form in datasheet view or when I try to refresh Form.
If I use the field filter in the Datasheet view I get an error:"Enter a valid value"
If i try to refresh Form by using F5 key I get an error: "Data provider could not be initialized"
If I use linked tables to SQL Server and use those tables as record source for the Form none of the problems described occur.
This is the code I use to set forms Recordset:
Private Sub Form_Load()
Dim ConnString As String
Dim cnn As ADODB.Connection
Dim rs As ADODB.Recordset
ConnString= "Provider=sqloledb;Server=xxx; Database=yyyyy; user Id=zzzz; password=uuuu;"
     Set cnn = New ADODB.Connection
     cnn.ConnectionString = ConnString
     cnn.Open
     Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open "select Field1, Field2, Field3 from dbo.TableA", cnn, adOpenStatic, adLockPessimistic
Set Me.Recordset = rs
End sub
It is also interesting that no matter what cursorType I use (adOpenStatic in this example), I'm always able to edit and add records in the form.
Is it at all possible to use Access functionality (filters, refresh) with ADO recordsets?

Ad. 1 see this https://codekabinett.com/rdumps.php?Lang=2&targetDoc=sort-filter-access-form-bound-adodb-recordset
Ad. 2 On Form_Error use this:
Private Sub Form_Error(DataErr As Integer, Response As Integer)
Const NO_DATA_SUPPLIER As Integer = 31
If DataErr = NO_DATA_SUPPLIER Then
Response = acDataErrContinue
'in this line you have to reasign your datasource for form
End If
End Sub

Related

ADODB.recordset AddNew/Update Method Error -2147467259 (80004005)

I've been getting the following error when trying to write data from my HMI to a MSSQL db using ADODB.recordset with the AddNew/Update Methods. I'm using SQL Server Native Client 11.0 for the connection and Microsoft ActiveX Data Objects 6.0 Library.
Generic VBA Error -2147467259[Microsoft][SQL Server Native Client 11.0][SQL Server]FNGCO,ABCDEFGHI,1000003,2017-04-14,17:00:36:187,FOAML1,A1,,1
If it works this code should write each value to each column in the MSSQL database. I've got very similar code working in another part of the application, but I can't seem to get this working.
What I Have Tried So Far:
Checked against code running in another HMI, everything between the two appears to be identical.
Tried the same connection string with another ADODB.recordset and added data to the db with AddNew/Update.
Checked the database table to make sure all of the data I'm trying to enter fits the column (its not null, max characters not exceeded, etc...)
Here is my code:
On debug, the code halts at sqlrs1.Update.
Option Explicit
Const strSQLNCLI11_1 = "Driver={SQL Server Native Client 11.0};Server=TESTDEMO\SQLEXPRESS;Database=RABPI;Uid=sa;Pwd=testdemo;QueryTimeout=0"'
Private Sub Button1_Released()
On Error GoTo ErrHandler
Dim sqlcn2 As ADODB.Connection
Dim sqlrs1 As ADODB.Recordset
Set sqlcn2 = New ADODB.Connection
Set sqlrs1 = New ADODB.Recordset
sqlcn2.Open strSQLNCLI11_1
sqlrs1.Open "Select * from AT_BW_PRDN ;", _
sqlcn2, adOpenDynamic, adLockPessimistic
sqlrs1.AddNew
sqlrs1("AT_BW_BUS_UNIT") = "FNGCO"
sqlrs1("AT_BW_PID") = "ABCDEFGHI"
sqlrs1("AT_BW_PRDN_AREA") = "FOAML1"
sqlrs1("AT_BW_SHIFT") = "A1"
sqlrs1("AT_BW_ITEM_ID") = "1000007"
sqlrs1("AT_BW_REL") = 0
sqlrs1.Update
Exit Sub
ErrHandler:
LogDiagnosticsMessage "Generic VBA Error" & Err.Number & " " & Err.Description, ftDiagSeverityError, ftDiagAudienceOperator
Set sqlcn2 = Nothing
Set sqlrs1 = Nothing
Exit Sub
End Sub
UPDATE:
I made a test database and re-created the tables I'm trying to write to without any constraints or triggers and the code functioned properly.

How to create an update query with Open Office Base?

I want to create basically an update query on Open Office Base (the same way with Ms ACCESS).
Base does not typically use update queries (but see below). Instead, the easiest way to do an update command is to go to Tools -> SQL. Enter something similar to the following, then press Execute:
UPDATE "Table1" SET "Value" = 'BBB' WHERE ID = 0
The other way is to run the command with a macro. Here is an example using Basic:
Sub UpdateSQL
REM Run an SQL command on a table in LibreOffice Base
Context = CreateUnoService("com.sun.star.sdb.DatabaseContext")
databaseURLOrRegisteredName = "file:///C:/Users/JimStandard/Desktop/New Database.odb"
Db = Context.getByName(databaseURLOrRegisteredName )
Conn = Db.getConnection("","") 'username & password pair - HSQL default blank
Stmt = Conn.createStatement()
'strSQL = "INSERT INTO ""Table1"" (ID,""Value"") VALUES (3,'DDD')"
strSQL = "UPDATE ""Table1"" SET ""Value"" = 'CCC' WHERE ID = 0"
Stmt.executeUpdate(strSQL)
Conn.close()
End Sub
Note that the data can also be modified with a form or by editing the table directly.
Under some circumstances it is possible to create an update query. I couldn't get this to work with the default built-in HSQLDB 1.8 engine, but it worked with MYSQL.
In the Queries section, Create Query in SQL View
Click the toolbar button to Run SQL Command directly.
Enter a command like the following:
update mytable set mycolumn = 'This is some text.' where ID = 59;
Hit F5 to run the query.
It gives an error that The data content could not be loaded, but it still performs the update and changes the data. To get rid of the error, the command needs to return a value. For example, I created this stored procedure in MYSQL:
DELIMITER $$
CREATE PROCEDURE update_val
(
IN id_in INT,
IN newval_in VARCHAR(100)
)
BEGIN
UPDATE test_table SET value = newval_in WHERE id = id_in;
SELECT id, value FROM test_table WHERE id = id_in;
END
$$
DELIMITER ;
Then this query in LibreOffice Base modifies the data without giving any errors:
CALL update_val(2,'HHH')
See also:
https://forum.openoffice.org/en/forum/viewtopic.php?f=5&t=75763
https://forum.openoffice.org/en/forum/viewtopic.php?f=61&t=6655
https://ask.libreoffice.org/en/question/32700/how-to-create-an-update-query-in-base-sql/
Modifying table entries from LibreOffice Base, possible?

PXDatabase should accept PXDbType.Udt in Acumatica ERP

How can I call a stored procedure in Acumatica via PXDataBase which has as input parameter User defined type?
For example, I have the following type:
CREATE TYPE [dbo].[string_list_tblType] AS TABLE(
[RefNbr] [nvarchar](10) NOT NULL,
PRIMARY KEY CLUSTERED
(
[RefNbr] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
I have the following stored procedure:
CREATE PROCEDURE [dbo].[GetListOfAPInvoices]
#APInvoices as string_list_tblType readonly,
AS
BEGIN
select * from APInvoice a where a.RefNbr in (select RefNbr from #APInvoices)
END
and following fragment of C# code:
var par = new SqlParameter("APInvoices", dt);
par.SqlDbType = SqlDbType.Structured;
par.TypeName = "dbo.string_list_tblType";
par.UdtTypeName = "dbo.string_list_tblType";
par.ParameterName = "APInvoices";
PXSPParameter p1 = new PXSPInParameter("#APInvoices", PXDbType.Udt, par);
var pars = new List<PXSPParameter> { p1};
var results = PXDatabase.Execute(sqlCommand, pars.ToArray());
but when I execute my C# code I'm receiving error message:
UdtTypeName property must be set for UDT parameters
When I debugged with reflector class PXSqlDatabaseProvider, method
public override object[] Execute(string procedureName, params PXSPParameter[] pars)
I noticed that
using (new PXLongOperation.PXUntouchedScope(Thread.CurrentThread))
{
command.ExecuteNonQuery();
}
command.Parameters.Items has my method parameters, but item which is related to Udt type is null. I need to know how to pass user defined table type. Has anybody tried this approach?
Unfortunately UDT parameters are not supported in Acumatica's PXDatabase.Execute(..) method and there is no way to pass one to a stored procedure using the built-in functionality of the platform.
Besides, when writing data-retrieval procedures like the one in your example, you should acknowledge that BQL-based data-retrieval facilities do a lot of work to match company masks, filter out records marked as DeletedDatabaseRecord and apply some other internal logic. If you chose to fetch data with plain select wrapped into a stored procedure you bypass all this functionality. Hardly is this something that you want to achieve.
If you absolutely want to use a stored procedure to get some records from the database but don't want the above side-effect, one option is to create an auxiliary table in the DB and select records into it using a procedure. Then in the application you add a DAC mapped to this new table and use it to get data from the table by means of PXSelect or similar thing.
Coming back to your particular example of fetching some ARInvoices by the list of their numbers, you could try using dynamic BQL composition to achieve something like this with Acumatica data access facilities.

What is the type (none,scaler,entity,complex) if store procedure return multiple ouptput parameter in entity framework in mvc4

I have created a mvc4 application with entity framework. Added a entity model in project. Now i have
added a store procedure in model browser and editing import function. There is a option Returns a collection of which contains none,scalers,complex,entities. I am not able to decide which one to choose as my store procedure returns multiple output parameters. If it returns single parameter then i can choose scalers, if table then entities. But it returns more then one output parameter so which one to choose. I am attaching store procedure screen shot.
Your stored procedure uses reference parameters, but doesn't actually return anything. To make a stored procedure return something, end the procedure with a SELECT statement that doesn't set a variable.
So, your code with look something like this:
CREATE PROC [wickedbrains].[uspValidateAdminLogin]
#UserName VARCHAR(50),
#Password VARCHAR(50)
AS
BEGIN
DECLARE #UserId INT = NULL,
#Res INT = 0;
IF EXISTS(SELECT '' FROM tblAdminUser WHERE UserName = #UserName AND Pwd = #Password)
BEGIN
SELECT #UserId = Id FROM tblAdminUser WHERE UserName = #UserName AND Pwd = #Password;
SET #Res = 1;
END
SELECT #UserId, #Res;
END
Once you've fixed your stored procedure, as Ehsan described, you can fix your imported stored procedure after the fact by clicking Get Column Information, then clicking Create New Complex Type.
If you absolutely have to use output parameters, you will have to retrieve the parameters with code as you would with reference parameters used in any other function. The point is that stored procedures that only use output parameters don't have a return type. See this answer for further details: https://stackoverflow.com/a/6193419/12116036

SQL Results Not Returned to C#

SETUP:
asp.net MVC
SQL SERVER 2008 R2
I have a procedure to get a list of messages to send. I want to update the results records so I cannot accidentally pull the same records twice. Regardless of how I approach it, SSMS produces the correct list of messages. However, if I update the records in the same procedure, C# does not get any results.
I have tried using a DataAdapter like this:
var da = new SqlDataAdapter(cmd);
da.Fill(table);
and DataReader like this:
var dataReader = cmd.ExecuteReader();
table.Load(dataReader);
dataReader.Close();
to populate my DataTable, neither seems to affect the results.
My procedure looks like this:
ALTER PROCEDURE [dbo].[MnxNoticeGetMessages]
#sessionId uniqueidentifier = null
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Output TABLE (messageid uniqueidentifier)
INSERT INTO #Output
SELECT messageid FROM MnxTriggerEmails WHERE dateSent is null
SELECT * FROM MnxTriggerEmails WHERE messageid IN (SELECT messageid FROM #Output)
UPDATE MnxTriggerEmails SET dateSent=GETDATE()
WHERE messageid IN (SELECT * FROM #Output)
END
This produces results in SSMS but not in C#.
If I comment out the UPDATE like this (no other changes):
--UPDATE MnxTriggerEmails SET dateSent=GETDATE()
-- WHERE messageid IN (SELECT * FROM #Output)
I get the expected results in both SSMS and C#.
What am I missing? What would cause this? How do I update the records AND get the results at the same time?
Your code looks fine. It should work. It almost sounds like you are calling the sp twice. The first time changes the dates and the second returns no results. This would cause ssms to produce the desired results and c# to be empty.
Check the code you haven't posted and see if you make that call again before populating the DataTable.

Resources