I have a Delphi 2007 app that interacts with an Access 2000 database. I have made changes to the database structure (addition of fields) and need to make them visible in the Delphi application but that is proving difficult. I made a minimal Delphi application and Access database and the same issue is seen there.
My steps were:
create an Access database with Field 1 and Field2
use Settings/Control Panel/Administrative Tools/Data Sources (ODBC 32-bit) to create an alias to the MS database.
create a Delphi application.
add a TDBGrid to the form
add a TDataSource onto the form
set the Datasource property of the grid to DataSource1
add a TTable to the form
set the Dataset property of the TDataSource to Table1
set the DataBaseName property of Table1 to the alias name created for the database.
set the TableName property to the name of the table in your original Access database.
set the Active property of the Table to TRUE. All the fields originally defined in the database appear in the grid.
The problem is when I want to add fields later to this. I can make them appear as columns in the grid by rebuilding the whole thing from scratch, but there must be an easier way!
What is accepted best practice for forcing database structure changes through to the Delphi IDE and resulting application?
** Answer to Ken White's comment **
Thanks Ken. I appreciate the reasons for the Columns property of the DBGrid when you may not want all the fields in your grid - my issue is that when I use MS Access to add some fields to the table and then re-open my Delphi project:
if I disconnect the TTable and reconnect it, the FieldDefs property shows the added fields. All good.
I then move to the TDBGrid. The displayed columns don't show the additional fields, only the original ones. The Columns collection is empty.
when I inspect the Columns property and try to add all fields I just get the original fields. If I try to add one field` column, the picklist only gives me the original fields to choose from.
I don't understand why the TTable can see the new fields but the TDatasource (which has the TTable specified as it's Dataset property value) cannot.
Related
I have basic knowledge of MS SQL which actually sabotages me as the syntax differs from MySQL in which I need the code written.
I have X databases named "project_%". It's 1 database per project. I need a script or a procedure (it's gonna be rarely used by support) that's gonna take some user info from master DB and add a list of users (or at least a single user) into all (later a list might be required) "project_%" databases.
My idea was to create a variable/temp table to fill with the list of databases and run a cycle (for/while) to set a default schema and insert required data. This is where I'm stuck as I have no idea how to set default schema from a variable or to input the variable into variable_db.table.
What I've found so far always differed from what I needed and couldn't apply it to my code.
Thanks,
Z
I updated the SCHEMA of a live table in MySQL for use in my multi-user database. Each user has their own db and links to the production tables through ODBC.
I have been receiving a write error while trying to test my schema updates. I cannot find the core reason. I hypothesized that because the other users are in the production table but have not been relinked to update the table SCHEMA; That it is causing a conflicting write error on my relinked table.
I added a TINYINT with No NULLS and default value of 0
I double checked all datatypes for incompatibility & have tested the "non relinked" tables in a older version of the DB and confirmed it is working as intended with no errors
I expect/want to be able to edit records without a write error, but am hesitant to update the other users to the new table if it is currently having write errors
After changing the schema of a linked table, it's required to refresh the link on all Access databases connected to it.
You can do this on the ribbon through external data -> linked table manager.
Unfortunately, either all users that have a database need to do this manually, unless you automate the task on startup through vba.
You have two separate issues. To "see" new columns, then yes, you must re-link the tables.
(so above is separate question and separate issue). You thus as a general rule can add new columns to the database (even while in use). However, the client side linked tables will not see the new columns until such time you re-link. This approach (adding new columns, but not yet re-linked from Access) is certainly ok and fine - the only downside is end users can't see nor use the new columns until such time you link. From a developer point of view, this good - since your users will not see nor find new columns until such time you roll out a new front end to each work station.
Ok, now problem and issue number two.
As for adding a new column, then re-linking, and THEN having some issue is really a separate issue. In most cases, if you attempting to use a tiny int as a Boolean (and I think that is your case), then you need to ensure several things:
Do not allow nulls (you seem to have this ok).
Make sure you set a default of 0 (server side) for this column. (you might have not allowed nulls, but without a default, then Access likely will still complain. And this default is important during creating time - since the new column needs to be "filled" with zeros.
Make sure the table has a PK defined.
Consider adding a row version column (I think mySQL has these, not sure but they can help immensely).
I have made up Tracker form in Access 2013 in which end user update their daily routine tasks. I want to keep the table as read-only so that no one can make any unauthorized changes in the existing data.
Is there any way to do that in Access?
One solution would be to
move the reference table into a separate database file,
make that file read-only (e.g., by using Windows permissions on the file), and
use a Linked Table in the main database to access the reference table.
Use a query in place of the table, and change its Recordset Type property to Snapshot.
If you want to avoid users opening the table itself, move the table to another database and change the Source property of the table to the path of the other database. In SQL it gives something slike:
SELECT * FROM myTable IN 'f:\test\hidden.mdb'
AFAIK you cannot make a table read only, but you can do a number of things to lock down the database so that the user only has access to forms that are read only.
In Options deselect:
Use Access Special Keys
Display Navigation Pane
Allow Full menus
Allow Default Shortcut Menus
In the form, set the following properties to No:
Allow Additions
Allow Deletions
Allow edits
I am converting a Large MS Access 2010 application to act as a front end to MySQL 5.5 database, via the v5.1 ODBC Connector, and I am experiencing a strange problem when inserting new records with bound data forms.
In a data-entry form, if the default value of a date field is set in the properties of the control as a constant (such as #04-01-2014#) the new record is created in MySQL successfully, and after saving, all fields are visible in their associated bound fields. But if the default value is defined in the Access control as a function (example: =Date()) then although the MySQL row is created successfully, ODBC fails to find the new row and Access displays all values as #DELETED. Refresh and/or requery commands are not helpful. This is nothing to do with the well known issue of -- must have a primary key and a datestamp in MySQL. All of these safeguards are in place, and as stated, it does work without FE defaults.
No defaults are being set in the MySQL backend, and it makes no difference whether or not Nulls are allowed. Data type used in the backend is DateTime. If I do set defaults in the BE and none in the FE, everything is fine. But that way, the user DOES NOT SEE THE DEFAULTS in the data entry form... an unacceptable situation.
I have also tested both ODBC v5.2, and MySQL 5.6 with exactly the same results.
A solution that seems to work (so far) is to set all defaults in code, in the form.beforeUpdate event. Something like this:
form_beforeUpdate()
if me.newrecord then
field1.value = date()
field2.value = fOtherDate()
'etc
end if
'other code
exit sub
I could insert all new records with unbound forms and passthrough queries. But with 75,000 lines of code, that is a very big job
My question is - why do I need these "workarounds"? Isn't the whole purpose of ODBC to allow fairly normal operation? What is it about simple functions that "breaks it"? What other "ordinary" Access methods will break it? If I don't understand why it didn't work I can't be sure it is properly fixed.
Has anyone else had any experience with this SPECIFIC issue? I could not find any reference to it elsewhere. Thank you for your time.
I am trying to create an SSIS package for integrating between MSSQL and MYSQL. I have no prior experience of working with Bids or SSIS and following the instructions from here.
I added the OLE DB Source, Lookup, Conditional Split, OLE DB Destination and OLE DB Command components to the Data Flow and configured the connection managers and column mappings upto the Conditional Split component.
From here, I am facing two problems -
1) After configuring the OLE DB Destination, it shows error symbol on the component that says could not convert between unicode and non unicode string datatypes. To solve this, I tried to insert a Data Conversion Component between the Conditional Split and the Destination and configured it for the problematic column. But that doesnt seem to help
2) While configuring the OLE DB Command, the right hand side column in Column mappings tab shows zero columns. I have added the Sql command with question marks so i guess it should be showing columns named "Param_0", "Param_1" etc if i am not wrong. I even tried to add them manually from the input and output properties tab but then it shows the warning, external columns for OLE DB command are out of sync with data source
What am I missing here ?
Thanks
The way you describe your first problem, it sounds like it should work. Here are a couple of things to check.
The data conversion component creates a new column for the converted data. Make sure you are referring to it in your following transformations and destination.
Right-click on the Data Conversion component and select Advanced Editor. Select the Input and Output Properties tab in the Advanced Editor. Expand the Data Conversion Output branch of the tree-view and select your new column. Ensure that the Data Type Properties show the data type that you want to convert too. If these values are not right then something is not right with the setup in the component.
For your second problem, the issue can frequently be caused by an error with the SqlCommand value. First, make sure the Connection Manager is correct on the Connection Manager tab. Switch to the Column Mappings tab. Near the bottom of the form, there may be a warning message that indicates that the SQL statement cannot be prepared. In other words, SSIS can't figure out what the statement is supposed to do. Address any problems with the SQL statement and switch back to the Column Mappings tab. The columns will appear once the SQL statement can be parsed.
If you want to avoid the conversion issues then change your destination table column types from char/varchar to nchar/nvarchar. I'm pretty sure you will need to use an ADO connector for mysql source and destinations, you should be able to read data from the mysql source and write to the mssql database w/o using anything other than source and destination components.