"No value for parameter" error message - delphi

I'm new to Delphi7.
When I try to use the editor's "Add all fields" feature on a TClientDataSet object a messagebox (the classic error message box) appear with the message "No value for parameter '(the name of the parameter)'".
I can't add fields using the "all fields" feature anymore.
How can I find the source of the "No value for parameter" error?

The problem is (most likely) that the ClientDataSet is not filled with any data.
Lacking data, no fields can be listed.
Do the following:
put a connection on the form. [connection1]
Connect it to a database fill in login, password, database, and whatnot.
Make the connection active. (only possible if all the connection parameters are filled in correctly).
put a table on the form. [table1]
Set it's connection property to connection1.
Set the tablename property to a valid table; set active to true.
Put a datasetprovider on the form. [datasetprovider1]
Set the dataset to table1.
Put a clientdataset on your form [cds1].
Set the providername of cds1 to datasetprovider1.
Set cds1.Active to true
Now you can select fields, because now the cds holds actual data.

I managed by myself. The TClientDataSet object had a parameter with DataType and ParamType properties both set to Unknown. Setting the parameter with correct properties solved the problem, I was able to "add all fields" again. Thanks for the answers.

I don't think any data is necessary to do what you want - and the first answer provided does not seem to include data, even though that is the original statement. You should be able to add all fields so long as you have a connection to a table, query, stored procedure or something similar.
Your question says there is no value for a parameter, and shows which parameter - although you don't say. But it is probably the parameter for a query or such. That query is failing because you are not providing a parameter, therefore you don't get any results. Of course this includes no fields.
Check the parameter in the error message.

Related

How do I add data to a database in Delphi by using edits instead of a DBNavigator?

My interface is very basic. It just includes edits for the user to input data into a database, when they click the button i want it to add the data into my database.
You can easily do this.
Go to the Data Controls tab of the Component palette.
Select a TDBEdit and place it on the same form as your DBNavigator. The IDE will name this DBEdit1
Set the Datasource property of your DBEdit1 to the same datasource as your DBNavigator.
Set the DataField property of DBEdit1 to the name of a field in your dataset.
Compile and run.
That's it. Leave your DBNavigator on your form because you will find that when you make a change to the contents of DBEdit1, its Save and Cancel buttons automatically enable to let you save or cancel the change.
Also, you'll find that if you click your DBNavigator's '+' button, which begins the insertion of a new record into your table, you can then type the field values for the new record into your DBEdits.
Don't use normal non-DB-aware TEdit components and a dynamically-created Sql statement which concatenates the TEdits's contents with other Sql as suggested in the other answer which briefly appeared here and now seems to have been deleted - it is a waste of time, but much more importantly renders your app vulnerable to Sql-Injection - see https://en.wikipedia.org/wiki/SQL_injection. By sending the server an unverified Sql statement which includes what the user has typed into a TEdit, you're effectively providing the user with an opportunity to type additional Sql statements into the TEdit and that is exactly how Sql injection can occur. On the other hand, when you use TDBEdits, the Sql for updating the database record is automatically generated by Delphi's TDataSet framework in a way which does not provide a similar opportunity for Sql Injection.
If some reason you absolutely have to generate your own Sql Update statements, to minimise the risk of Sql Injection, make sure that you use a parameterised Update statement, that is, one where the changed field values are specified as values of parameters in your TDataSet-descendant's Parameters object, rather than in the Update Sql itself. An example of a parameterised Update statement might be:
Update MyTable set FieldA =:FieldA, FieldB=:FieldB where RowID =:RowID
where :FieldA, :FieldB and :RowID are the parameters.

Updating stored procedure Entity framework throw "verify that the FunctionImport name is unique" error

I am using EF v4.3 and I have a problem in updating a stored procedure.
I the Model Browser I selected the stored procedure I want to update (it has a Function Import and a Complex type that I want to update).
I right clicked and selected Add Function Import. The usual window opens.
My first problem is that EF does not automatically pick up the fact that there is already a complex type defined since the "return a Collection Of" radio button is set to None instead of Complex.
Anyway, I selected the correct complex type and pressed the "Update" button. The stored procedure box is populated with the correct complex type and the rows that need to be changed are marked as "Update" in the action column.
I pressed OK and a message box is displayed with the error message "Verify that the FunctionImport name is Unique".
I can solve this problem by deleting the Function Import but I do not want to do it every time. Why is the update not working? What am I doing wrong?
Thanks for any help you can provide.
Michele
Here is a screenshot to show what you need to do, either delete the existing one or update per OP's comment:

How to retrieve information from a field that has the property Required set as false?

I have the following DBX structure in my software:
TSQLDataSet -> TDataSetProvider -> TClientDataSet
One of the fields from my TClientDataSet has the property Required set to false, because this field auto increments based on triggers and generators on the database (Firebird).
However, after configuring both TSQLDataSet and TClientDataSet with this field not being required, I'm getting really weird results when I try to read this field from my TClientDataSet. I suspect that I might need to do something extra to force my TClientDataSet to acquire the value of this field in this condition.
What am I missing here?
Thanks in advance.
EDIT
The help file for the Required property says something about this, but I couldn't quite understand what it want me to do.
Description
Specifies whether a nonblank value for a field is
required.
Use Required to find out if a field requires a value or if the field
can be blank.
If a field is created with the Fields editor, this property is set
based on the underlying table. Applications that set Required to true
for fields that must have values (for example, a password or part
number), but for which the underlying table does not require the
field, must write an OnValidate event handler to enforce the property.
When the Required property reflects a property of the underlying
database table, trying to post apply a null value causes an exception
to be raised. Applications that set the Required property to true when
the underlying table does not require the field, should raise an
EDatabaseError exception on null values in the OnValidate event
handler in order to achieve the same result.
EDIT 2
Forgot to mention: between the TDataSetProvider and the TClientDataSet, there is a DataSnap layer (the TClientDataSet connection is made with a DataSnap driver).
EDIT 3
I created a small test case with this DataSnap setup and it worked perfectly. The project is legacy, messy and I guess that either I have an obscure option configured somewhere that is biting me or I have stumbled in a DataSnap bug.
Haole, have you tried TClientDataset.RefreshRecord after inserting? Or even TClientDataset.Refresh?
Having generators, you can even get the generator in advance (before calling ApplyUpdates) in a query like select gen_id(generator,1) from RDB$Database (it's from memory, don't have Firebird here to test) and fill the PK field in advance.
EDIT: seems this is a heisenbug. I would try to remove the components and reconfigure them again from scratch (which means: after you remove, save and close Delphi).
Or even better, create an empty project with just that needed query configuration and try to view that data in a TDBGrid. If this problem still happens, maybe your FB installation have some component corrupted (or even Delphi installation)
Seems that the problem was an outdated field being read as an INTEGER and it was a SMALLINT in the database.
This problem was hard to debug and this question was misleading. Thanks for everyone that helped me debug this.

Delphi - ClientDataSet - validating data

I have an application in Delphi 7 which is using a clientdataset, and make several operations on it. ClientDataSet is linked to an Intraweb Grid.
I make an insert or an edit on the ClientDataSet. How can I verify the data introduced in the clientdataset for each field? I can not verify the input from the user on the webform, so I must make validation using ClientDataSet events.
LE: I want to validate data when the user make the input. Not at the onbeforepost event. So, I put the clientdataset in the edit/insert. User make an input in the grid, and I want to validate the data for that row in the clientdataset like in the image bellow:
first column is string, second is integer, the third one is also an integer. Now, I want to validate the third column after the user make the input. This validation must be done (if it is possible), only by using clientdataset events/hacks.
You should handle TClientDataset BeforePost event, and if data is not valid use abort method
TField has an OnValidate event for that purpose. It has also a CustomConstrain property that can use a SQL like syntax for constraints. DefaultExpression will let you select a value if no value is given. These are usuful for single-field validation. If you need more complex checks across more than one field, then you have to use dataset or datasource events.
Anyway, if the Intraweb grid sends the server whole records and not single fields edits, you may not validate fields as they are entered in the grid but adding code client side.
If you want a field based validation, you can handle the OnDataChange event of the TDatasource connecting the grid to the dataset. This will be triggered whenever a field has been changed by the user. You should be aware that it will also be triggered in some other situations.

Initialize task form fields with infopath form values

I'm trying to initialize a task form (in my workflow) with values contained in my infopath form (the global one if I could call it like this ^^).
For example, I've a worflow which is activated on a command from a client. The first task is assigned to the client, he has to fill in a form with some values (command name, adress, ...).
Next, I save those values to my "global" infopath form. It works.
After that, I create a task for the command manager who get a summary of the command and he has to validate it or not. In this form, I want to retrieve values from the global form. This is the problem.
I tried to use a data connection on the global infopath form and set the default value of the field in the task form. For example, the command name : #CommandName. And it doesn't retrieve any value...
I don't know if you need more information and if you guys understand my question cause it can be a bit confused. So don't hesitate to ask me question to clarify.
This issue is solved now.
My workaround :
Define a Content Type for each fields.
Add extended properties to the task with the name of your field :
myTaskProperties.ExtendedProperties["myFieldName"] = "my expected value";
This is the way to pre-fill your form by the code.
To retrieve data from your global infopath form :
I've a method which do that. This method is going to read the xml (my global infopath) and get the value. After that, I add this value instead of "my expected value" above.
If you want more explanation or code, don't hesitate to contact me.

Resources