Thread: PL/pgSQL syntax for strings
Could someone please tell me the correct syntax for the following problem in plpgsql: The following expression code sample works but now (for example) I'd like to subsitute the variables $1 and $2 for the numbers 0 and 2 in the following expression: INSERT INTO rtest(xz,yz,xy) VALUES ( \'(0,2), (1,3)\', \'(1,2), (2,3)\', \'(0,1), (1,2)\'); What's the correct way of represinting the strings? A complete code example is below. It's to do with the usage of R-tree indexing. Eddy edward.grabczewski@btinternet.com =============================================================== DROP TABLE rtest; DROP INDEX rtest_xz_index; DROP INDEX rtest_yz_index; DROP INDEX rtest_xy_index; CREATE TABLE rtest ( xz BOX, yz BOX, xy BOX); CREATE INDEX rtest_xz_index ON rtest USING RTREE (xz bigbox_ops); CREATE INDEX rtest_yz_index ON rtest USING RTREE (yz bigbox_ops); CREATE INDEX rtest_xy_index ON rtest USING RTREE (xy bigbox_ops); DROP FUNCTION threedpoint (float,float,float, float,float,float); CREATE FUNCTION threedpoint (float,float,float,float,float,float) RETURNS text AS 'DECLARE x1 ALIAS FOR $1; y1 ALIAS FOR $2; z1 ALIAS FOR $3; x2 ALIAS FOR $4; y2 ALIAS FOR $5; z2 ALIAS FOR $6; BEGIN INSERT INTO rtest(xz,yz,xy) VALUES ( \'(0,2), (1,3)\', \'(1,2), (2,3)\', \'(0,1), (1,2)\'); RETURN null; END;' LANGUAGE 'plpgsql'; SELECT threedpoint(100,200,300,400,500,600); SELECT * FROM rtest ORDER BY xz USING <<; SELECT xz, yz, xy FROM rtest WHERE xz @ '(1.0,3.0),(0.0,2.0)'::box AND yz @ '(2.0,3.0),(1.0,2.0)'::box AND xy @ '(1.0,2.0),(0.0,1.0)'::box ORDER BY xz USING <<; ======================================================== -- Eddy Grabczewski edward.grabczewski@btinternet.com
On Thu, Nov 01, 2001 at 04:48:29PM +0000, Edward Grabczewski wrote: > > DROP FUNCTION threedpoint (float,float,float, float,float,float); > CREATE FUNCTION threedpoint (float,float,float,float,float,float) > RETURNS text > AS 'DECLARE > x1 ALIAS FOR $1; > y1 ALIAS FOR $2; > z1 ALIAS FOR $3; > x2 ALIAS FOR $4; > y2 ALIAS FOR $5; > z2 ALIAS FOR $6; > BEGIN > INSERT INTO rtest(xz,yz,xy) > VALUES ( \'(0,2), (1,3)\', > \'(1,2), (2,3)\', > \'(0,1), (1,2)\'); > RETURN null; > END;' > LANGUAGE 'plpgsql'; > > SELECT threedpoint(100,200,300,400,500,600); Why do you pass all those variables to the function if you don't use them? It doesn't make any sense to me. As the documentation for PL/pgSQL clearly states with several examples, you have to double the quotes in strings> INSERT INTO rtest(xz,yz,xy) VALUES (''(0,2), (1,3)'', ''(1,2), (2,3)'', ''(0,1), (1,2)''); I don't know if the \' way of escaping quotes works. I never tried within a PL/pgSQL function. My guess is that it doesn't. -Roberto -- +----| http://fslc.usu.edu USU Free Software & GNU/Linux Club |------+ Roberto Mello - Computer Science, USU - http://www.brasileiro.net http://www.sdl.usu.edu - Space Dynamics Lab, Developer My inferiority complexes aren't as good as yours.
Sorry about the function not makig sense. It's only half-baked until I get this string thing sorted out. I left the hard-coded numerical values there for testing purposes only - so I guess it confused everyone. As it happens the syntax of the posted function actually works. Even the backslashes! Now the trick is to incorporate the variables into the string. I've looked at the documentation a few times and I've experimented but failed to get the right syntax so far - which is why I thought I'd ask for some help. :-) Below is what the function will eventually look like when it uses the proper variables: I guessed that the single quote needs to be double quoted: ''''('' x1 '','' z1 ''), ('' x2 '','' z2 '')'''' or something like that. Should this work? Eddy CREATE TABLE rtest ( xz BOX, yz BOX, xy BOX); CREATE INDEX rtest_xz_index ON rtest USING RTREE (xz bigbox_ops); CREATE INDEX rtest_yz_index ON rtest USING RTREE (yz bigbox_ops); CREATE INDEX rtest_xy_index ON rtest USING RTREE (xy bigbox_ops); DROP FUNCTION threedpoint (float,float,float, float,float,float); CREATE FUNCTION threedpoint (float,float,float,float,float,float) RETURNS text AS 'DECLARE x1 ALIAS FOR $1; y1 ALIAS FOR $2; z1 ALIAS FOR $3; x2 ALIAS FOR $4; y2 ALIAS FOR $5; z2 ALIAS FOR $6; BEGIN INSERT INTO rtest(xz,yz,xy) VALUES ( '(x1,z1), (x2,z2)', '(y1,y2),(y2,z2)', '(x1,y1), (x2,y2)'); RETURN null; END;' LANGUAGE 'plpgsql'; SELECT threedpoint(100,200,300,400,500,600);
I've sorted this one thanks to John Berkus. Thanks guys. I've included the solution below for your interest. ======================================================= DROP TABLE rtest; DROP INDEX rtest_xz_index; DROP INDEX rtest_yz_index; DROP INDEX rtest_xy_index; CREATE TABLE rtest ( xz BOX, yz BOX, xy BOX); CREATE INDEX rtest_xz_index ON rtest USING RTREE (xz bigbox_ops); CREATE INDEX rtest_yz_index ON rtest USING RTREE (yz bigbox_ops); CREATE INDEX rtest_xy_index ON rtest USING RTREE (xy bigbox_ops); DROP FUNCTION cube (float,float,float, float,float,float); CREATE FUNCTION cube (float,float,float,float,float,float) RETURNS text AS 'DECLARE x1 ALIAS FOR $1; y1 ALIAS FOR $2; z1 ALIAS FOR $3; x2 ALIAS FOR $4; y2 ALIAS FOR $5; z2 ALIAS FOR $6; xz_ BOX; yz_ BOX; xy_ BOX; left VARCHAR; right VARCHAR; BEGIN left :=to_char(x1,''99999.999'') || '','' || to_char(z1,''99999.999''); right := to_char(x2,''99999.999'') || '','' || to_char(z2,''99999.999''); xz_ := left || '','' || right; left := to_char(y1,''99999.999'') || '','' || to_char(z1,''99999.999''); right := to_char(y2,''99999.999'') || '','' || to_char(z2,''99999.999''); yz_ := left || '','' || right; left := to_char(x1,''99999.999'') || '','' || to_char(y1,''99999.999''); right := to_char(x2,''99999.999'') || '','' || to_char(y2,''99999.999''); xy_ := left || '','' || right; INSERT INTO rtest(xz,yz,xy) VALUES (xz_, yz_, xy_); RETURN null; END;' LANGUAGE 'plpgsql'; SELECT cube(1,2,3,10,20,30); SELECT * FROM rtest ORDER BY xz USING <<; SELECT xy, yz, xz FROM rtest WHERE xz @ '(0.0,0.0),(2.5,2.5)'::box AND yz @ '(0.0,0.0),(2.5,2.5)'::box AND xy @ '(0.0,0.0),(2.5,2.5)'::box ORDER BY xy USING <<;