TypeError: argument must be sequence of values - cursor

I am using an insert cursor to put all of the values for the field "Size" into all of the rows in my dbf. Here is the code that I am using:
for i in range(0,144779):
cursor2=arcpy.da.InsertCursor("Distance_Table.dbf",["Size"])
cursor2.insertRow(1)
#Delete cursor object
del cursor2
I know that the last record in the table was 144,779. I put it into the range statement to see whether the value of the variable I had calculated was causing the error and it was not. I keep getting this message "TypeError: argument must be sequence of values." I am putting the same size value in all and I will use an update cursor to update the values.

You should create the cursor first, then iterate over your range of values. Here, you create a new cursor for each iteration.
Also, the row object you insert is a tuple and it should be enclosed with round brackets, even if there is only 1 field:
cursor2 = arcpy.da.InsertCursor("Distance_Table.dbf",["Size"])
for i in range(0,144779):
cursor2.insertRow((1))
#Delete cursor object
del cursor2

Related

PL/SQL - Declare a record where keep records of a table and an operation?

I'm currently trying to figure out a question on my assignment. I've never worked with arrays before but I've done collections, triggers, functions, procedures, and cursors. I'm not asking for the answer but rather some help on this as I'm confused on how to approach it.
Declare a record where you keep record of LOCATIONS table (LOCATION_ID,
STREET_ADDRESS, POSTAL_CODE, CITY, STATE_PROVINCE and
COUNTRY_ID) and an operation.
Declare an array where you keep location records as elements.
Initialize the array by populating values for each location that you would like
to process
The operation type can be ‘U’ for Update, ‘I’ for Insert and ‘D’ for Delete
Iterate all array elements from beginning to end and execute the following
logic per each location defined in the array:
If operation type is ‘U’, then update LOCATIONS table with the values
coming from the array. If location id is not found on the table, insert it
as a new record.
If operation type is ‘I’, insert the record to the table. Values should
come from the array
If operation type is ‘D’, delete that location from the table.
For each operation, display a message after the process is completed
If operator type is different than U, I, D, then display a proper
message indicating 'Invalid operation'.
Commit all transactions
The part about the operations also confuses me because I have done some work where you would use the operators in triggers but it didn't involve an array:
BEGIN
IF INSERTING THEN
INSERT INTO carlog
VALUES ('INSERT',user, SYSDATE, UPPER(:NEW.serial), UPPER(:NEW.make),
UPPER(:NEW.model), UPPER(:NEW.color));
END IF;
IF UPDATING THEN
INSERT INTO carlog
VALUES ('UPDATE',user, SYSDATE,:old.serial, old.make,
old.model, old.color);
END IF;
IF DELETING THEN
INSERT INTO carlog
VALUES ('DELETE',user, SYSDATE,:old.serial, old.make,
old.model, old.color);
END IF;
END;
An array is just a type of collection. If you look at the documentation here: https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/collections.htm#LNPLS00501
You can see that an "Associative Array" is simply a PL/SQL collection type.
As far as the "Operation" is concerned, my understanding based on the spec is that it is purely an attribute of the location record itself. I would make something similar to the below:
DECLARE
--declare your location record based on the spec
TYPE location IS RECORD (
location_id integer,
operation VARCHAR2(1)
--additional values from the spec would go here
);
--declare an array as a table of the location type
TYPE location_array IS TABLE OF location INDEX BY BINARY_INTEGER;
--two variables to hold the data
example_location location;
locations location_array;
BEGIN
--start building your location record for the location you want to modify
example_location.location_id := 1;
example_location.operation := 'T';
--..... additional values here
--add the location to the array
locations(locations.count + 1) := example_location;
--repeat the above for any other locations, or populate these some other way
--loop through the locations
FOR i IN locations.first..locations.last
LOOP
--decide the logic based on the operation, could just as easily use your if logic here
CASE locations(i).operation
WHEN 'U' THEN
dbms_output.put_line('your update logic here');
WHEN 'I' THEN
dbms_output.put_line('your insert logic here');
WHEN 'D' THEN
dbms_output.put_line('your delete logic here');
ELSE
dbms_output.put_line('other operations');
END CASE;
END LOOP;
END;
You would need to adapt the above to suit your needs, adding in the relevant logic, messages, commits, error handling etc.

Updating a table field with variables

Can someone help me please...I am running the following query but it keeps failing.
I want to replace the S with RS in the field (there are other variables in the same field) but only want to replace the S variables to RS
update
MDSCLMDTL
set
STATUS_CODE= 'rs' where STATUS_CODE ='s'
Try using Replace Function
update
MDSCLMDTL
set
STATUS_CODE= Replace(STATUS_CODE,'s','rs')
where charindex('s',STATUS_CODE)> 0 -- To filter the rows which doesnot have 's' character

Pl/Sql array inside a statement

I'm trying to prepare a function, so I've started this sql sketch to figure out how to manage my situation:
DECLARE
x XMLType;
begin
x := XMLType('<?xml version="1.0"?>
<ROWSET>
<ROW>
<START_DATETIME>29/05/2015 14:23:00</START_DATETIME>
</ROW>
<ROW>
<START_DATETIME>29/05/2015 17:09:00</START_DATETIME>
</ROW>
</ROWSET>');
FOR r IN (
SELECT ExtractValue(Value(p),'/ROW/START_DATETIME/text()') as deleted
FROM TABLE(XMLSequence(Extract(x,'/ROWSET/ROW'))) p
) LOOP
-- do whatever you want with r.name, r.state, r.city
-- dbms_output.put_line( 'TO_DATE('''|| r.deleted ||''', '''|| 'DD/MM/YYYY HH24:MI:SS'')');
dbms_output.put_line( ''''|| r.deleted ||'''');
DELETE FROM MYTABLE a WHERE a.START_DATETIME not in (''''|| r.deleted || '''');
END LOOP;
END;
I've tried different ways to perform the query after the loop has filled the variable but is gaves me a conversion error:
00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
incorrect. The input data did not contain a number where a number was
required by the format model.
*Action: Fix the input data or the date format model to make sure the
elements match in number and type. Then retry the operation.
Can anybody help me?
thanks!
You're wrapping a string in explicit single quotes; that is making the quotes part of the string itself, which you don't want.
You need to convert the string to a data type, which you are sort of doing in a commented-out section - in that case you do need the extra quotes for your dbms_output() to make it a text literal, and to end up as a valid to_date() call; so you end up with output from that:
TO_DATE('29/05/2015 14:23:00', 'DD/MM/YYYY HH24:MI:SS')
But for your delete though you just need to do:
DELETE FROM MYTABLE a
WHERE a.START_DATETIME not in (to_date(r.deleted, 'DD/MM/YYYY HH24:MI:SS'));
The reference to r.deleted is already a string, so you refer to it directly, with no additional quotes.
You only have a single value though, so at that point in the loop using not in is not necessary and you can use != instead:
DELETE FROM MYTABLE
WHERE START_DATETIME != to_date(r.deleted, 'DD/MM/YYYY HH24:MI:SS');
Your title mentions an array, so perhaps you really intend to put all the values from the XML into a (schema-level type) table collection and then use that in the not in clause, so it removes everything except the dates in your XML. Doing it individually like this will effectively delete everything in the table if there is more than one date in the XML, which also suggests you either want to use an array, and/or actually meant in or = to only remove those.
Incidentally, extractValue() is deprecated, so it would be better to use XMLQuery or XMLTable, e.g.:
FOR r IN (
SELECT *
FROM XMLTable('/ROWSET/ROW/START_DATETIME'
PASSING x COLUMNS deleted VARCHAR2(19) PATH '.')
) LOOP

Avoid Adding Duplicate Records

I m trying to write if statement to give error message if user try to add existing ID number.When i try to enter existing id i get error .untill here it s ok but when i type another id no and fill the fields(name,adress etc) it doesnt go to database.
METHOD add_employee.
DATA: IT_EMP TYPE TABLE OF ZEMPLOYEE_20.
DATA:WA_EMP TYPE ZEMPLOYEE_20.
Data: l_count type i value '2'.
SELECT * FROM ZEMPLOYEE_20 INTO TABLE IT_EMP.
LOOP AT IT_EMP INTO WA_EMP.
IF wa_emp-EMPLOYEE_ID eq pa_id.
l_count = l_count * '0'.
else.
l_count = l_count * '1'.
endif.
endloop.
If l_count eq '2'.
WA_EMP-EMPLOYEE_ID = C_ID.
WA_EMP-EMPLOYEE_NAME = C_NAME.
WA_EMP-EMPLOYEE_ADDRESS = C_ADD.
WA_EMP-EMPLOYEE_SALARY = C_SAL.
WA_EMP-EMPLOYEE_TYPE = C_TYPE.
APPEND wa_emp TO it_emp.
INSERT ZEMPLOYEE_20 FROM TABLE it_emp.
CALL FUNCTION 'POPUP_TO_DISPLAY_TEXT'
EXPORTING
TITEL = 'INFO'
TEXTLINE1 = 'Record Added Successfully.'.
elseif l_count eq '0'.
CALL FUNCTION 'POPUP_TO_DISPLAY_TEXT'
EXPORTING
TITEL = 'INFO'
TEXTLINE1 = 'Selected ID already in database.Please type another ID no.'.
ENDIF.
ENDMETHOD.
I'm not sure I'm getting your explanation. Why are you trying to re-insert all the existing entries back into the table? You're just trying to insert C_ID etc if it doesn't exist yet? Why do you need all the existing entries for that?
If so, throw out that select and the loop completely, you don't need it. You have a few options...
Just read the table with your single entry
SELECT SINGLE * FROM ztable INTO wa WITH KEY ID = C_ID etc.
IF SY-SUBRC = 0.
"this entry exists. popup!
ENDIF.
Use a modify statement
This will overwrite duplicate entries with new data (so non key fields may change this way), it wont fail. No need for a popup.
MODIFY ztable FROM wa.
Catch the SQL exceptions instead of making it dump
If the update fails because of an exception, you can always catch it and deal with exceptional situations.
TRY .
INSERT ztable FROM wa.
CATCH sapsql_array_insert_duprec.
"do your popup, the update failed because of duplicate records
ENDTRY.
I think there's a bug when appending in internal table 'IT_EMP' and inserting in 'ZEMPLOYEE_20' table.
Suppose you append the first time and then you insert. But when you append the second time you will have 2 records in 'IT_EMP' that are going to be inserted in 'ZEMPLOYEE_20'. That is because you don't refresh or clear the internal table and there you will have a runtime error.
According to SAP documentation on 'Inserting Lines into Tables ':
Inserting Several Lines
To insert several lines into a database table, use the following:
INSERT FROM TABLE [ACCEPTING DUPLICATE KEYS] . This
writes all lines of the internal table to the database table in
one single operation. The same rules apply to the line type of
as to the work area described above. If the system is able to
insert all of the lines from the internal table, SY-SUBRC is set to 0.
If one or more lines cannot be inserted because the database already
contains a line with the same primary key, a runtime error occurs.
Maybe the right direction here is trying to insert the work area directly but before you must check if record already exists using the primary key.
Check the SAP documentation on this issue clicking the link before.
On the other hand, once l_count is zero because of l_count = l_count * '0'. that value will never change to any other number making that you won't append or insert again.
why are you retrieving all entries from zemployee_20 ?
You can directly check wether the 'id' exists already or not by using select single. If exists, then show message, if not, add.
It is recommended to retrieve only one field when its needed and not the entire table with asterisc *
SELECT single employee_id FROM ZEMPLOYEE_20 where employee_id = p_id INTO v_id. ( or field in structure )
if sy-subrc = 0. "exists
"show message
else. "not existing id
"populate structure and then add record to Z table
endif.
Furthermore, l_count is not only unnecessary but also bad implemented.
You can directly use the insert query,if the sy-subrc is unsuccessful raise the error message.
WA_EMP-EMPLOYEE_ID = C_ID.
WA_EMP-EMPLOYEE_NAME = C_NAME.
WA_EMP-EMPLOYEE_ADDRESS = C_ADD.
WA_EMP-EMPLOYEE_SALARY = C_SAL.
WA_EMP-EMPLOYEE_TYPE = C_TYPE.
INSERT ZEMPLOYEE_20 FROM WA_EMP.
If sy-subrc <> 0.
Raise the Exception.
Endif.

Getting "Multiple-step operation generated errors" In ASP Classic Using Merged Data Set Function

I am using a function I read about here to merge a series of recordsets that are generated by a stored procedure that is called in a loop. I have used this function before in other stored procedure cases and it has never produced this problem.
The research I did online points to basically one of two reasons:
1) I am trying to update or insert a date/time value that is not formatted correctly into a SQL Server 2005 table
2) I am trying to insert a, for example, CHAR(60) string into a CHAR(50) field.
Reason one is not applicable here since I am not using dates (in datetime format at least).
Reason two seemed to be the most likely issue. So I did a series of Response.Write() to spit out the objField.Name, objField.Type, objField.ActualSize, and if it was a numeric field the objField.Precision and objField.NumericScale.
Let us say that the stored SQL procedure is called twice as I am querying for values that are occurring in the same time frame but 2 different states. The loop I have in the ASP page does a For Each on the state in the state list and calls the stored procedure for each of the elements in the state list. I then call the MergeRecordSets function so it combines the 2 results into one. The general rule is that the data types and sizes of the columns in each resultset must be the same. With my Response.Write() checks of each of the columns returned in the 2 data sets I have found that they are identical. Doing my checks I also found that it breaks on the first column that is a NUMERIC column. The previous columns it was OK with were all CHAR or VARCHAR.
Is there any other reason why this error would come up?
The following is how I am calling the record merger function. The oQueryResult is going to be the final output (the combined records). objSingleRS is the result set returned by the stored procedure.
If oQueryResult Is Nothing Then
Set oQueryResult = objSingleRS
Else
Set oQueryResult = MergeRecordSets(Array(oQueryResult, objSingleRS))
End If
Here is the merge function. The line in which the code breaks is marked below.
Function MergeRecordSets(arrRecordsets)
Dim x, y, objCurrentRS
Dim objMergedRecordSet, objField, blnExists
Set objMergedRecordSet = Server.CreateObject("ADODB.Recordset")
For x=0 To UBound(arrRecordsets)
Set objCurrentRS = arrRecordsets(x)
For Each objField In objCurrentRS.Fields
blnExists = False
For y=0 To objMergedRecordSet.Fields.Count-1
If LCase(objMergedRecordSet.Fields(y).Name) = Lcase(objField.Name) Then
blnExists = True : Exit For
End If
Next
If Not(blnExists) Then
objMergedRecordSet.Fields.Append objField.Name, objField.Type, objField.DefinedSize
'objMergedRecordSet.Fields(objMergedRecordset.Fields.Count-1).Attributes = 32 'adFldIsNullable
End If
Next
Next
objMergedRecordSet.Open
For x=0 To UBound(arrRecordsets)
Set objCurrentRS = arrRecordsets(x)
Do Until objCurrentRS.EOF
objMergedRecordSet.AddNew
For Each objField In objCurrentRS.Fields
If Not(IsNull(objField.Value)) Then
'Response.Write(objField.Name & "<br>")
'Response.Write(objField.Type & "<br>")
objMergedRecordSet.Fields(objField.Name).Value = objField.Value 'Here is where it throws the Error.
End If
Next
objCurrentRS.MoveNext
Loop
Next
objMergedRecordSet.MoveFirst
Set MergeRecordSets = objMergedRecordSet
End Function
Here is the full error message returned:
Microsoft Cursor Engine error '80040e21'
Multiple-step operation generated errors. Check each status value.
/includes/funcs/Common.asp, line 4109
You mentioned that you have numeric columns, but you never set the Precision and NumericScale properties when you create the new Field in objMergedRecordSet. You need to set these properties for adNumeric and adDecimal fields.
objMergedRecordSet.Fields.Append objField.Name, objField.Type, objField.DefinedSize
With objMergedRecordSet.Fields(objField.Name)
.Precision = objField.Precision
.NumericScale = objField.NumericScale
End With
Also make sure you are not trying to put a NULL into a column that will not accept a NULL value. There is also the possibility of a type mismatch to cause this error so make sure you are passing a numeric value.
- Freddo

Resources