Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to convert update statement into Replace command in foxpro

Status
Not open for further replies.

Niki_S

Programmer
Jun 4, 2021
232
LK
This is my update statement and I want to convert it into a replace command.
Code:
SELECT UPDT 
SCAN 
	UPDATE Delshdvl SET Pcs=UPDT.Pcs ;
	WHERE Pln_Cd=UPDT.Pln_Cd AND Shp_Style=UPDT.Shp_Style AND Lot=UPDT.Lot 
ENDSCAN
How can do this?

Thank you
 
There are a lot of ways to do this, I prefer

Code:
SELECT UPDT
SCAN
	** SELECT THE TARGET REPLACE WORKAREA
	SELECT DELSHDVL
	REPLACE PCS WITH UPDT.PCS FOR PLN_CD=UPDT.PLN_CD .AND. SHP_STYLE=UPDT.SHP_STYLE .AND. LOT=UPDT.LOT
	** SCAN WILL RESELECT UPDT
ENDSCAN

But it could be suggested that I am wasting a SELECT statement, this should work:
Code:
SELECT UPDT
SCAN
	REPLACE DELSHDVL.PCS WITH UPDT.PCS FOR DELSHDVL.PLN_CD=UPDT.PLN_CD .AND. DELSHDVL.SHP_STYLE=UPDT.SHP_STYLE .AND. DELSHDVL.LOT=UPDT.LOT
ENDSCAN

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Thanks Mike.

A thought, ENDSCAN would support further clarity if there was a deep nesting of some kind

Like
Code:
SELECT UPDT
SCAN &&UPDT
    .. do something
ENDSCAN && UPDT

Rather like a for next loop


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
An index, or two, could make it more efficient...

Code:
SELECT DELSHDVL
INDEX ON PLN_CD+SHP_STYLE+LOT TAG DELSHDVL
SELECT UPDT
SCAN && UPDT
	SELECT DELSHDVL
	SET ORDER TO DELSHDVL
	**  PLN_CD+SHP_STYLE+LOT
	SEEK (UPDT.PLN_CD+UPDT.SHP_STYLE+UPDT.LOT)
	DO WHILE .NOT. EOF() .AND. PLN_CD+SHP_STYLE+LOT = (UPDT.PLN_CD+UPDT.SHP_STYLE+UPDT.LOT)
		REPLACE DELSHDVL.PCS WITH UPDT.PCS 
		SKIP
	ENDDO
ENDSCAN && UPDT

Or if you prefer SCAN/ENDSCAN

Code:
SELECT DELSHDVL
INDEX ON PLN_CD+SHP_STYLE+LOT TAG DELSHDVL
SELECT UPDT
SCAN && UPDT
	SELECT DELSHDVL
	SET ORDER TO DELSHDVL
	**  PLN_CD+SHP_STYLE+LOT
	SEEK (UPDT.PLN_CD+UPDT.SHP_STYLE+UPDT.LOT)
	SCAN WHILE PLN_CD+SHP_STYLE+LOT = (UPDT.PLN_CD+UPDT.SHP_STYLE+UPDT.LOT) && DELSHDVL
		REPLACE DELSHDVL.PCS WITH UPDT.PCS 
	ENDSCAN && DELSHDVL
ENDSCAN && UPDT

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
I would go the other route, change this SCAN..ENDSCAN to a single UPDATE-SQL:

Code:
UPDATE Delshdvl SET Pcs=UPDT.Pcs FROM Delshdvl ;
INNER JOIN UPDT ON Pln_Cd=UPDT.Pln_Cd AND Shp_Style=UPDT.Shp_Style AND Lot=UPDT.Lot



Chriss
 
I tried in this way,
Code:
UPDATE _DelDtl SET Delvr_Pcs=UPDT.Delvr_Pcs FROM _DelDtl ;
INNER JOIN UPDT ON Style=UPDT.Style AND nStylecode=UPDT.nStylecode AND cLotName=UPDT.cLotName
But it says "STYLE is not unique and must be qualified".

 
Maybe change it thusish:

Code:
UPDATE _DelDtl SET Delvr_Pcs=UPDT.Delvr_Pcs FROM _DelDtl ;
INNER JOIN UPDT ON _DelDtl.Style=UPDT.Style AND nStylecode=UPDT.nStylecode AND cLotName=UPDT.cLotName

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Thank you for the helps. Now it's working[bigsmile]
 
thusish, good.

Well "STYLE is not unique" menas it's a field of both tables "must be qualified" means the name must be extended, therefore, to become explicitly meaning the style field of the table you need.

And I see you got that working. I assume your update now is:
Code:
UPDATE _DelDtl SET Delvr_Pcs=UPDT.Delvr_Pcs FROM _DelDtl ;
INNER JOIN UPDT ON _DelDtl.Style=UPDT.Style AND _DelDtl.nStylecode=UPDT.nStylecode AND _DelDtl.cLotName=UPDT.cLotName

I assumed a field name without table prefix would be assumedto mean the field of the main table you update and that's firstin the FROM clause.

And just to complete this: Thiskind of update is called correlated update, correlated to another table with a subquery, and is only possible with VFP9s extended sql engine. It's mentioned in the chapter SL Language Improvements:

That's not saying you should have found it, but I want to point out using SQL makes more sense even on the VFP side with all it's new possibilities, and especially to you, Niki, as you work with an SQL Server backend and so practicing SQL will always improve your usage of both VFP and SQL Server and the combination of both.

Chriss
 
You can use the old fashioned way:

Code:
*SELECT updt
*SCAN
*    UPDATE Delshdvl ;
*        SET Pcs=UPDT.Pcs ;
*        WHERE   Pln_Cd    = UPDT.Pln_Cd ;
*            AND Shp_Style = UPDT.Shp_Style ;
*            AND Lot       = UPDT.Lot
*
*ENDSCAN

#define theKey Pln_Cd + Shp_Style + Lot
SELECT updt
INDEX ON theKey TAG tmpKey

SELECT Delshdvl
SET RELATION TO theKey INTO updt
REPLACE ALL pcs WITH updt.pcs FOR NOT EOF("updt")

SET RELATION OFF INTO updt

SELECT updt
DELETE TAG tmpKey
* And if you do this regularly, you can define the key and not have to create it or delete it

The relationship will automatically advance the pointer into updt each time the record in delshdvl changes. So it's constantly doing the SEEK for you automatically behind the scenes.

This kind of XBASE equivalent command lets you debug / step through your records using a SCAN .. ENDSCAN with a single REPLACE instead of a REPLACE ALL, and you can examine each one to see why it's working or not working.

Very powerful debugging tools in learning XBASE commands, and they're not that much slower than more modern SQL equivalents.

Note: This is the meat of the algorithm:

Code:
#define theKey Pln_Cd + Shp_Style + Lot
SELECT Delshdvl
SET RELATION TO theKey INTO updt
REPLACE ALL pcs WITH updt.pcs FOR NOT EOF("updt")

The rest just supports this portion.

--
Rick C. Hodgin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top