Data type mismatch in foxpro stored procedure - stored-procedures

I want to make a copy of every record inserted in jobact to a new table jobactupdates. I am using a stored procedure for this purpose. Both tables are exactly the same and have same no of columns. When I insert data in jobact using insert query then, the stored procedure fails and show the Data Type mismatch error.
My code looks like this:
PROCEDURE insertData
INSERT INTO jobactupdates (jobcode ,jobdescr ,fileno ,port ,mastcode ,mastdescr ,mastdescr1 ,shipper ,goods ,unit1 ,qty ,unit ,vesname ,arremarks ,arrdate ,remarks ,docstat ,docdate ,blno ,bldate ,jastat ,rate ,demand ,received ,balance ,transpor,dldate);
VALUES(jobact.jobcode,jobact.jobdescr,jobact.fileno,jobact.port,jobact.mastcode,jobact.mastdescr,jobact.mastdescr1,jobact.shipper,jobact.goods,jobact.unit1,jobact.qty,jobact.unit,jobact.vesname,jobact.arremarks,jobact.arrdate,jobact.remarks,jobact.docstat,jobact.docdate,jobact.blno,jobact.bldate,jobact.jastat,jobact.rate,jobact.received,jobact.balance,jobact.transpor,jobact.dldate);
ENDPROC

A Data Type Mismatch error occurs when you try to insert an inappropriate data type into a field. For example, if you try to store a string into an integer field. I would double check the table structures and confirm that they are identical.
Another thing to be aware of is if any of the JOBACT field types are set to Integer (AutoInc). They will have to be set to just Integer in the JOBACTUPDATES table. Otherwise you will get a "Field is read-only" error message.

For
Character fields: write them into '' marks,
Numeric fields: just numbers for example 123,
Date fields: {^yyyy-mm-dd}
(There can also optionally be time in Date field.)

Is this your actual query? If so, the fact your Columns and Values clauses contain different field lists has certainly caused this error:
Insert Into ...
bldate,
jastat,
rate,
demand,
received,
balance ..
Values ...
jobact.bldate,
jobact.jastat,
jobact.rate,
jobact.received, <--
jobact.balance, <--
jobact.transpor <--
.

Related

How to generate dynamic values in fitnesse

I have to insert incremental values in a column of the table using Fitnesse. The incremental value I'll get from a stored procedure which returns the last inserted value. So I have to increment the value and store it.
For example: I'll get a value from the stored procedure output. And I have to increment the value by 1 and insert into the table.
Any ideas?
Output from stored procedure is like : ACRDE0001 (PK)
Value to store in table : ACRDE0002, ACRDE0003, .....
Expected output
!|insert|table1|
|col1|col2|col3|
|ACRDE0001|abc|def|
|ACRDE0002|abc|def|
|ACRDE0003|abc|def|
.
.
.
.
As far as I'm aware the only way to change (e.g. increment) a value you get during your test is by writing some code in a fixture. There is a pull request to allow more dynamic Slim expression directly in the wiki, but that has not been merged (let alone released) yet.
Your questions suggests that the value is something you get from a database and that you then want to send back the generated/incremented value with new records you insert. In that case I wonder whether the increment is actually that useful to actually have in your wiki (your test case is not about the generated values, is it?).
Maybe your fixture could just retrieve the initial value (or have it supplied as constructor value) and the fixture could generate the a new value for each row and send them to the database.

TFDQuery and SQLite: Type mismatch for field, expecting: LargeInt actual: WideString

Using Delphi 10.2, SQLite and Teecharts. My SQLite database has two fields, created with:
CREATE TABLE HistoryRuntime ('DayTime' DateTime, Device1 INTEGER DEFAULT (0));
I access the table using a TFDQuery called qryGrpahRuntime with the following SQL:
SELECT DayTime AS TheDate, Sum(Device1) As DeviceTotal
FROM HistoryRuntime
WHERE (DayTime >= "2017-06-01") and (DayTime <= "2017-06-26")
Group by Date(DayTime)
Using the Field Editor in the Delphi IDE, I can add two persistent fields, getting TheDate as a TDateTimeField and DeviceTotal as a TLargeIntField.
I run this query in a program to create a TeeChart, which I created at design time. As long as the query returns some records, all this works. However, if there are no records for the requested dates, I get an EDatabaseError exception with the message:
qryGrpahRuntime: Type mismatch for field 'DeviceTotal', expecting: LargeInt actual: Widestring
I have done plenty of searching for solutions on the web on how to prevent this error on an empty query, but have had not luck with anything I found. From what I can tell, SQLite defaults to the wide string field when no data is returned. I have tried using CAST in the query and it did not seem to make any difference.
If I remove the persistent fields, the query will open without problems on an empty return set. However, in order to use the TeeChart editor in the IDE, it appears I need persistent fields.
Is there a way I can make this work with persistent fields, or am I going to have to throw out the persistent fields and then add the TeeChart Series at runtime?
This behavior is described in Adjusting FireDAC Mapping chapter of the FireDAC's SQLite manual:
For an expression in a SELECT list, SQLite avoids type name
information. When the result set is not empty, FireDAC uses the value
data types from the first record. When empty, FireDAC describes those
columns as dtWideString. To explicitly specify the column data type,
append ::<type name> to the column alias:
SELECT count(*) as "cnt::INT" FROM mytab
So modify your command e.g. this way (I used BIGINT, but you can use any pseudo data type that maps to a 64-bit signed integer data type and is not auto incrementing, which corresponds to your persistent TLargeIntField field):
SELECT
DayTime AS "TheDate",
Sum(Device1) AS "DeviceTotal::BIGINT"
FROM
HistoryRuntime
WHERE
DayTime BETWEEN {d 2017-06-01} AND {d 2017-06-26}
GROUP BY
Date(DayTime)
P.S. I did a small optimization by using BETWEEN operator (which evaluates the column value only once), and used an escape sequence for date constants (which, in real you replace by parameter, I guess; so just for curiosity).
This data type hinting is parsed by the FDSQLiteTypeName2ADDataType procedure that takes and parses column name in format <column name>::<type name> in its AColName parameter.

Calc field doesn't post

Hi I want to post calc field(cemi) to table (sql). when I calc all field the last field doesn't post on sql table. because last field (cemi) type fkcalc how can I post fkcalc type field to sql table Thanks in advance!
procedure TForm1.ADOQuery1CalcFields(DataSet: TDataSet);
begin
ADOQuery1.FieldValues['cemi']:=
((ADOQuery1.FieldValues['boyuk1'] + ADOQuery1.FieldValues['boyuk2'] +
ADOQuery1.FieldValues['boyuk3'])*0.35)+((ADOQuery1.FieldValues['kicik1'] +
ADOQuery1.FieldValues['kicik2'])*0.25) +(ADOQuery1.FieldValues['qara1']*0.30);
end;
I'm not quite sure what you mean by
the last field doesn't post on sql table
If the "last field" you are referring to is your "Cemi" one and that is a column which is in the table on your SQL Server, it will not get posted back there if you have defined it as a calculated field in your AdoQuery1 in the Object Inspector. Fields with a FieldKind of fkCalculated are local to the AdoQuery.
Just assigning a value to the calculated field is sufficient to "post" it locally to the AdoQuery, as I imagine you know. What you want to do to debug your problem (because readers like me cannot debug it fr you) is to more easily see what value, if any, is being assigned to it.
From that point of view, your code is suffering from "premature optimisation" which will make it difficult for you to see what is going wrong. Try this instead:
In your ADOQuery1CalcFields, declare a local variable for each of the fields you are accessing, including the calculated one. Choose the variable types to suit the fields:
var
Boyuk1 : Double; // or Integer, etc
[...]
Cemi : Double;
Assign values to the local variables, using the AsXXXX (type) of the fields:
Cemi := 0;
if not AdoQuery1.FieldByName('Boyuk1').IsNull then
Cemi := Cemi + AdoQuery1.FieldByName('Boyuk1').AsFloat;
[etc]
That way, at least you'll be able to see the point at which the calculation goes wrong (if it does).
I've used FieldByName().AsFloat, rather than FieldValues[], because FieldValues[] is a Variant, which can be Null, and you don't want that when you are assigning values to it which mat themselves be variants.
Also
Check that AutoCalcFields is set to True for AdoQuery1.
Put a debugger breakpoint on the first line of ADOQuery1CalcFields. Compile and run and check that the breakpoint hits - if it doesn't, there's your answer. Single-step the debugger through each line of the procedure, and, after the final line, use Ctrl-F7 to evaluate the value of AdoQuery1.FieldByName('Cemi').AsFloat.

Sort DBGrid using column title

I am using Access database with delphi 7. I have created a DBGrid and am using Adoquery to show database with columns having students ID, Firstname and lastname titles with the exact field names format in the database. I have the following code to sort the column titles in ascending order.
procedure TReportsForm.DBGrid2DblClick(Sender: TObject);
var
str1: String;
begin
str1 := DBGrid2.SelectedField.FieldName;
ADOQuery1.Sort:= str1+' ASC';
end;
When I press the firstname and lastname column titles, the sorting works fine. However when I press the students ID results
I get error the message
EOleException: Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
Is this problem associated with numbers and characters fields and how can this be solved?
I think I know the problem.
You see, the function ADOQuery.Sort can be applied to 'WideString' data types. In your database, check what data type student ID is. If it is set as 'number' then obviously ADOQuery.Sort cannot be applied to it, it is an incompatible data type. Try changing the student ID field to 'Text' data type in your database, and retry and see if that works.
Also quick tip: In your database, if student ID is set as'number' then it might just be worth it to change it to text. BEcause it is a primary key (im assuming) and therefore no calculations are performed on the student ID, therefore it doesn't need to be stored as a number.
Hope this helped! ;)
You never accepted the above answer, so I assume it didn't help. I was wondering if the issue is with spaces in field names ("Student ID" for example). If so, the solution is to slightly change the code:
ADOQuery1.Sort:= '[' + str1 + '] ASC';
Cheers

How to match ets:match against a record in Erlang?

I have heard that specifying records through tuples in the code is a bad practice: I should always use record fields (#record_name{record_field = something}) instead of plain tuples {record_name, value1, value2, something}.
But how do I match the record against an ETS table? If I have a table with records, I can only match with the following:
ets:match(Table, {$1,$2,$3,something}
It is obvious that once I add some new fields to the record definition this pattern match will stop working.
Instead, I would like to use something like this:
ets:match(Table, #record_name{record_field=something})
Unfortunately, it returns an empty list.
The cause of your problem is what the unspecified fields are set to when you do a #record_name{record_field=something}. This is the syntax for creating a record, here you are creating a record/tuple which ETS will interpret as a pattern. When you create a record then all the unspecified fields will get their default values, either ones defined in the record definition or the default default value undefined.
So if you want to give fields specific values then you must explicitly do this in the record, for example #record_name{f1='$1',f2='$2',record_field=something}. Often when using records and ets you want to set all the unspecified fields to '_', the "don't care variable" for ets matching. There is a special syntax for this using the special, and otherwise illegal, field name _. For example #record_name{record_field=something,_='_'}.
Note that in your example you have set the the record name element in the tuple to '$1'. The tuple representing a record always has the record name as the first element. This means that when you create the ets table you should set the key position with {keypos,Pos} to something other than the default 1 otherwise there won't be any indexing and worse if you have a table of type 'set' or 'ordered_set' you will only get 1 element in the table. To get the index of a record field you can use the syntax #Record.Field, in your example #record_name.record_field.
Try using
ets:match(Table, #record_name{record_field=something, _='_'})
See this for explanation.
Format you are looking for is #record_name{record_field=something, _ = '_'}
http://www.erlang.org/doc/man/ets.html#match-2
http://www.erlang.org/doc/programming_examples/records.html (see 1.3 Creating a record)

Resources