<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: The Q-quote mechanism</title>
	<atom:link href="http://awads.net/wp/2006/03/30/the-q-quote-mechanism/feed/" rel="self" type="application/rss+xml" />
	<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/</link>
	<description>News, views, tips and tricks on Oracle and other fun stuff</description>
	<pubDate>Tue, 07 Oct 2008 07:06:03 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
		<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-51495</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Thu, 06 Sep 2007 14:35:56 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-51495</guid>
		<description>&lt;p&gt;Chander, thanks for posting an example. The Q-quote mechanism sure does make a programmer's life easier in many cases.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Chander, thanks for posting an example. The Q-quote mechanism sure does make a programmer&#8217;s life easier in many cases.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chander Sharma</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-51494</link>
		<dc:creator>Chander Sharma</dc:creator>
		<pubDate>Thu, 06 Sep 2007 06:50:29 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-51494</guid>
		<description>&lt;p&gt;The q function has solved a problem that I've struggled to resolve, where a script prompts for a value (that may include 1 or more quotes  e.g. a where clause) and I have to manipulate that value before I can use it. In this case the value is spooled out as part of a select to a file that will be 'started'.&lt;/p&gt;

&lt;p&gt;E.g.&lt;/p&gt;

var  v_where_clause     VARCHAR2(1024);

ACCEPT a_Where PROMPT  ' Enter a valid WHERE clause: '

&lt;p&gt;BEGIN
  --
  :v_where_clause := Q'[&#38;a_Where]';
  :v_where_clause := RTRIM(:v_where_clause, ' ;');
  IF LTRIM(UPPER(:v_where_clause)) LIKE 'WHERE%'
  THEN
    -- Clip the 'Where' clause from the point after the 'WHERE ' (if included)
    :v_where_clause := SUBSTR(:v_where_clause, INSTR(UPPER(:v_where_clause), 'WHERE ') + 6);
  END IF;
  --
END;
/&lt;/p&gt;

&lt;p&gt;Prior to this, the where clause had to use double-quotes (or pairs of single-quotes) around literals, as I couldn't 'capture' the value in a variable.&lt;/p&gt;

&lt;p&gt;The whole script follows. Needless to say this is less useful with modern IDE tools, but in our Live environment it has proved invaluabl.&lt;/p&gt;

SET ECHO OFF

&lt;p&gt;PROMPT vL2007/09/05.1
PROMPT 1) When prompted, enter the name of the TABLE for selection.
PROMPT 2) You may then add a simple WHERE clause, or  to default.
PROMPT 3) You may then add a simple ORDER BY clause, or  to default.
PROMPT 4) Note: DATE values should use the format DD-MON-YYYY.
PROMPT&lt;/p&gt;

SET HEADING OFF FEEDBACK OFF VERIFY OFF NUMWIDTH 12 TRIMSPOOL ON PAGESIZE 0 LINESIZE 200

ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';

&lt;p&gt;var  v_table_name       VARCHAR2(100);
var  v_owner            VARCHAR2(30);
var  v_where_clause     VARCHAR2(1024);
var  v_order_by         VARCHAR2(1024);
var  v_dot_posn         NUMBER;&lt;/p&gt;

&lt;p&gt;ACCEPT a_Tab   PROMPT  ' Enter the name of the required TABLE: '
ACCEPT a_Where PROMPT  ' Enter a valid WHERE clause: '
ACCEPT a_Order PROMPT  ' Enter a valid ORDER BY clause: '&lt;/p&gt;

&lt;p&gt;BEGIN
  --
  :v_table_name := NVL('&#38;a_Tab', 'Dual');
  :v_dot_posn   := INSTR(:v_table_name, '.');
  --
  IF NVL(:v_dot_posn, 0) &#62; 0
  THEN
    :v_owner      := SUBSTR(:v_table_name, 1, (:v_dot_posn - 1));
    :v_table_name := SUBSTR(:v_table_name, (:v_dot_posn + 1));
  ELSE
    :v_owner      := USER; -- or whatever defaulkt is required
  END IF;
  --
  :v_where_clause := Q'[&#38;a_Where]';
  :v_where_clause := RTRIM(:v_where_clause, ' ;');
  IF LTRIM(UPPER(:v_where_clause)) LIKE 'WHERE%'
  THEN
    -- Clip the 'Where' clause from the point after the 'WHERE ' (if included)
    :v_where_clause := SUBSTR(:v_where_clause, INSTR(UPPER(:v_where_clause), 'WHERE ') + 6);
  END IF;
  --
  :v_order_by := Q'[&#38;a_Order]';
  :v_order_by := RTRIM(:v_order_by, ' ;');
  IF LTRIM(UPPER(:v_order_by)) LIKE 'ORDER %BY %'
  THEN
    -- Clip the 'Order By' clause from the point after the ' BY ' (if included)
    :v_order_by := SUBSTR(:v_order_by, INSTR(UPPER(:v_order_by), ' BY ') + 4);
  END IF;
  --
END;
/&lt;/p&gt;

SET TERMOUT OFF

SPOOL TabSpool.sql

&lt;p&gt;SELECT 'SET ECHO OFF' &#124;&#124; CHR(10) &#124;&#124;
       'SET HEADING OFF FEEDBACK OFF PAGESIZE 0' &#124;&#124; CHR(10) &#124;&#124;
       'SET LINESIZE 70 ARRAYSIZE 5' &#124;&#124; CHR(10) &#124;&#124;
       'ALTER SESSION ENABLE PARALLEL DML;' &#124;&#124; CHR(10) &#124;&#124;
       'PROMPT'
  FROM Dual;&lt;/p&gt;

&lt;p&gt;SELECT 'SELECT /*+ APPEND PARALLEL(' &#124;&#124; :v_table_name &#124;&#124; ', 7) */'
  FROM Dual;&lt;/p&gt;

&lt;p&gt;SELECT '''' &#124;&#124; LPAD(RPAD(column_name, 30), 35) &#124;&#124; '= [' &#124;&#124;
       ''' &#124;&#124; ' &#124;&#124; column_name &#124;&#124; ' &#124;&#124; '']'','
  FROM all_tab_columns
 WHERE table_name = UPPER(:v_table_name)
   AND data_type IN ('CHAR', 'VARCHAR2', 'NUMBER', 'DATE')
   AND owner = UPPER(:v_owner)
 ORDER BY column_id ASC;&lt;/p&gt;

&lt;p&gt;SELECT ''' '' FROM ' &#124;&#124; :v_owner &#124;&#124; '.' &#124;&#124; :v_table_name &#124;&#124; ' WHERE ' &#124;&#124;
       NVL(:v_where_clause, '1=1') &#124;&#124;
       DECODE(:v_order_by, NULL, NULL, ' ORDER BY ' &#124;&#124; :v_order_by) &#124;&#124; ';'
  FROM Dual;&lt;/p&gt;

&lt;p&gt;SELECT 'SELECT CHR(32) FROM Dual;'
  FROM Dual;&lt;/p&gt;

&lt;p&gt;SELECT 'SET HEADING ON FEEDBACK ON PAGESIZE 100 LINESIZE 120 ECHO ON ' &#124;&#124;
       RPAD(' ',60)
  FROM Dual;&lt;/p&gt;

SPOOL OFF

&lt;p&gt;UNDEFINE a_Tab
UNDEFINE a_Where
UNDEFINE a_Order&lt;/p&gt;

SET HEADING ON FEEDBACK ON VERIFY ON ARRAYSIZE 20 TRIMSPOOL OFF PAGESIZE 100 LINESIZE 120 TERMOUT ON ECHO ON

START TabSpool.sql

SET ECHO OFF

&lt;p&gt;:&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>The q function has solved a problem that I&#8217;ve struggled to resolve, where a script prompts for a value (that may include 1 or more quotes  e.g. a where clause) and I have to manipulate that value before I can use it. In this case the value is spooled out as part of a select to a file that will be &#8217;started&#8217;.</p>
<p>E.g.</p>
<p>var  v_where_clause     VARCHAR2(1024);</p>
<p>ACCEPT a_Where PROMPT  &#8216; Enter a valid WHERE clause: &#8216;</p>
<p>BEGIN<br />
  &#8211;<br />
  :v_where_clause := Q&#8217;[&amp;a_Where]&#8217;;<br />
  :v_where_clause := RTRIM(:v_where_clause, &#8216; ;&#8217;);<br />
  IF LTRIM(UPPER(:v_where_clause)) LIKE &#8216;WHERE%&#8217;<br />
  THEN<br />
    &#8212; Clip the &#8216;Where&#8217; clause from the point after the &#8216;WHERE &#8216; (if included)<br />
    :v_where_clause := SUBSTR(:v_where_clause, INSTR(UPPER(:v_where_clause), &#8216;WHERE &#8216;) + 6);<br />
  END IF;<br />
  &#8211;<br />
END;<br />
/</p>
<p>Prior to this, the where clause had to use double-quotes (or pairs of single-quotes) around literals, as I couldn&#8217;t &#8216;capture&#8217; the value in a variable.</p>
<p>The whole script follows. Needless to say this is less useful with modern IDE tools, but in our Live environment it has proved invaluabl.</p>
<p>SET ECHO OFF</p>
<p>PROMPT vL2007/09/05.1<br />
PROMPT 1) When prompted, enter the name of the TABLE for selection.<br />
PROMPT 2) You may then add a simple WHERE clause, or  to default.<br />
PROMPT 3) You may then add a simple ORDER BY clause, or  to default.<br />
PROMPT 4) Note: DATE values should use the format DD-MON-YYYY.<br />
PROMPT</p>
<p>SET HEADING OFF FEEDBACK OFF VERIFY OFF NUMWIDTH 12 TRIMSPOOL ON PAGESIZE 0 LINESIZE 200</p>
<p>ALTER SESSION SET NLS_DATE_FORMAT = &#8216;DD-MON-YYYY&#8217;;</p>
<p>var  v_table_name       VARCHAR2(100);<br />
var  v_owner            VARCHAR2(30);<br />
var  v_where_clause     VARCHAR2(1024);<br />
var  v_order_by         VARCHAR2(1024);<br />
var  v_dot_posn         NUMBER;</p>
<p>ACCEPT a_Tab   PROMPT  &#8216; Enter the name of the required TABLE: &#8216;<br />
ACCEPT a_Where PROMPT  &#8216; Enter a valid WHERE clause: &#8216;<br />
ACCEPT a_Order PROMPT  &#8216; Enter a valid ORDER BY clause: &#8216;</p>
<p>BEGIN<br />
  &#8211;<br />
  :v_table_name := NVL(&#8217;&amp;a_Tab&#8217;, &#8216;Dual&#8217;);<br />
  :v_dot_posn   := INSTR(:v_table_name, &#8216;.&#8217;);<br />
  &#8211;<br />
  IF NVL(:v_dot_posn, 0) &gt; 0<br />
  THEN<br />
    :v_owner      := SUBSTR(:v_table_name, 1, (:v_dot_posn - 1));<br />
    :v_table_name := SUBSTR(:v_table_name, (:v_dot_posn + 1));<br />
  ELSE<br />
    :v_owner      := USER; &#8212; or whatever defaulkt is required<br />
  END IF;<br />
  &#8211;<br />
  :v_where_clause := Q&#8217;[&amp;a_Where]&#8217;;<br />
  :v_where_clause := RTRIM(:v_where_clause, &#8216; ;&#8217;);<br />
  IF LTRIM(UPPER(:v_where_clause)) LIKE &#8216;WHERE%&#8217;<br />
  THEN<br />
    &#8212; Clip the &#8216;Where&#8217; clause from the point after the &#8216;WHERE &#8216; (if included)<br />
    :v_where_clause := SUBSTR(:v_where_clause, INSTR(UPPER(:v_where_clause), &#8216;WHERE &#8216;) + 6);<br />
  END IF;<br />
  &#8211;<br />
  :v_order_by := Q&#8217;[&amp;a_Order]&#8217;;<br />
  :v_order_by := RTRIM(:v_order_by, &#8216; ;&#8217;);<br />
  IF LTRIM(UPPER(:v_order_by)) LIKE &#8216;ORDER %BY %&#8217;<br />
  THEN<br />
    &#8212; Clip the &#8216;Order By&#8217; clause from the point after the &#8216; BY &#8216; (if included)<br />
    :v_order_by := SUBSTR(:v_order_by, INSTR(UPPER(:v_order_by), &#8216; BY &#8216;) + 4);<br />
  END IF;<br />
  &#8211;<br />
END;<br />
/</p>
<p>SET TERMOUT OFF</p>
<p>SPOOL TabSpool.sql</p>
<p>SELECT &#8216;SET ECHO OFF&#8217; || CHR(10) ||<br />
       &#8216;SET HEADING OFF FEEDBACK OFF PAGESIZE 0&#8242; || CHR(10) ||<br />
       &#8216;SET LINESIZE 70 ARRAYSIZE 5&#8242; || CHR(10) ||<br />
       &#8216;ALTER SESSION ENABLE PARALLEL DML;&#8217; || CHR(10) ||<br />
       &#8216;PROMPT&#8217;<br />
  FROM Dual;</p>
<p>SELECT &#8216;SELECT /*+ APPEND PARALLEL(&#8217; || :v_table_name || &#8216;, 7) */&#8217;<br />
  FROM Dual;</p>
<p>SELECT &#8221;&#8221; || LPAD(RPAD(column_name, 30), 35) || &#8216;= [&#8217; ||<br />
       &#8221;&#8217; || &#8216; || column_name || &#8216; || &#8221;]&#8221;,&#8217;<br />
  FROM all_tab_columns<br />
 WHERE table_name = UPPER(:v_table_name)<br />
   AND data_type IN (&#8217;CHAR&#8217;, &#8216;VARCHAR2&#8242;, &#8216;NUMBER&#8217;, &#8216;DATE&#8217;)<br />
   AND owner = UPPER(:v_owner)<br />
 ORDER BY column_id ASC;</p>
<p>SELECT &#8221;&#8217; &#8221; FROM &#8216; || :v_owner || &#8216;.&#8217; || :v_table_name || &#8216; WHERE &#8216; ||<br />
       NVL(:v_where_clause, &#8216;1=1&#8242;) ||<br />
       DECODE(:v_order_by, NULL, NULL, &#8216; ORDER BY &#8216; || :v_order_by) || &#8216;;&#8217;<br />
  FROM Dual;</p>
<p>SELECT &#8216;SELECT CHR(32) FROM Dual;&#8217;<br />
  FROM Dual;</p>
<p>SELECT &#8216;SET HEADING ON FEEDBACK ON PAGESIZE 100 LINESIZE 120 ECHO ON &#8216; ||<br />
       RPAD(&#8217; &#8216;,60)<br />
  FROM Dual;</p>
<p>SPOOL OFF</p>
<p>UNDEFINE a_Tab<br />
UNDEFINE a_Where<br />
UNDEFINE a_Order</p>
<p>SET HEADING ON FEEDBACK ON VERIFY ON ARRAYSIZE 20 TRIMSPOOL OFF PAGESIZE 100 LINESIZE 120 TERMOUT ON ECHO ON</p>
<p>START TabSpool.sql</p>
<p>SET ECHO OFF</p>
<p>:</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50460</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Fri, 30 Mar 2007 16:32:47 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50460</guid>
		<description>&lt;p&gt;Simon, thanks for the update. I have been bitten by the "Oracle home" syndrome before.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Simon, thanks for the update. I have been bitten by the &#8220;Oracle home&#8221; syndrome before.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Simon B</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50459</link>
		<dc:creator>Simon B</dc:creator>
		<pubDate>Fri, 30 Mar 2007 15:15:25 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50459</guid>
		<description>&lt;p&gt;There is a bug 2489201 but it does not appear to be publicly accessible.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>There is a bug 2489201 but it does not appear to be publicly accessible.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Simon B</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50458</link>
		<dc:creator>Simon B</dc:creator>
		<pubDate>Fri, 30 Mar 2007 14:31:57 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50458</guid>
		<description>&lt;p&gt;Turns out that it's a 9i and earlier bug, so it depends on which Oracle Home you use to connect to your DB.&lt;/p&gt;

&lt;p&gt;Our databases are all 10g but our Oracle client software ranges from 8.0 through to 10g R2. The guy from Oracle support said something along the lines of " ... as you know the parser used by the database matches the version of the oracle client used to connect."&lt;/p&gt;

&lt;p&gt;As we don't actually use any 9i clients we couldn't provide a business case for raising a bug.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Turns out that it&#8217;s a 9i and earlier bug, so it depends on which Oracle Home you use to connect to your DB.</p>
<p>Our databases are all 10g but our Oracle client software ranges from 8.0 through to 10g R2. The guy from Oracle support said something along the lines of &#8221; &#8230; as you know the parser used by the database matches the version of the oracle client used to connect.&#8221;</p>
<p>As we don&#8217;t actually use any 9i clients we couldn&#8217;t provide a business case for raising a bug.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50449</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Tue, 27 Mar 2007 15:55:52 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50449</guid>
		<description>&lt;p&gt;Simon, using SQL*Plus, the following worked fine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SQL&#62; connect hr/hr
Connected.
SQL&#62; SELECT q'&#60;'Data, he said, 'Make it so.'&#62;'
  2   FROM DUAL
  3  /

Q'&#60;'DATA,HESAID,'MAKEITSO.'&#62;'
-----------------------------
'Data, he said, 'Make it so.'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, it failed when I ran it in SQL Navigator.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Simon, using SQL*Plus, the following worked fine:</p>
<pre><code>SQL&gt; connect hr/hr
Connected.
SQL&gt; SELECT q'&lt;'Data, he said, 'Make it so.'&gt;'
  2   FROM DUAL
  3  /

Q'&lt;'DATA,HESAID,'MAKEITSO.'&gt;'
-----------------------------
'Data, he said, 'Make it so.'
</code></pre>
<p>However, it failed when I ran it in SQL Navigator.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Simon B</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50448</link>
		<dc:creator>Simon B</dc:creator>
		<pubDate>Tue, 27 Mar 2007 14:38:25 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50448</guid>
		<description>&lt;p&gt;not sure why but my single-quotes in the previuos comment have been turned into back and forward quotes?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>not sure why but my single-quotes in the previuos comment have been turned into back and forward quotes?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Simon B</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50447</link>
		<dc:creator>Simon B</dc:creator>
		<pubDate>Tue, 27 Mar 2007 14:35:47 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-50447</guid>
		<description>&lt;p&gt;However an odd number of single-quotes within the string makes it fail.  Am I missing something here?&lt;/p&gt;

&lt;p&gt;SELECT q'&#60;'Data, he said, 'Make it so.'&#62;' 
    FROM DUAL;&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>However an odd number of single-quotes within the string makes it fail.  Am I missing something here?</p>
<p>SELECT q&#8217;&lt;&#8217;Data, he said, &#8216;Make it so.&#8217;&gt;&#8217;<br />
    FROM DUAL;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eddie Awad</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-4117</link>
		<dc:creator>Eddie Awad</dc:creator>
		<pubDate>Sun, 02 Apr 2006 00:21:40 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-4117</guid>
		<description>&lt;p&gt;So, the reason Oracle introduced this q-quote mechanism is to make string literals, containing single quotes, more readable, especially when escaping with the traditional approach results in a hard to read strings.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>So, the reason Oracle introduced this q-quote mechanism is to make string literals, containing single quotes, more readable, especially when escaping with the traditional approach results in a hard to read strings.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tim Hall</title>
		<link>http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-3697</link>
		<dc:creator>Tim Hall</dc:creator>
		<pubDate>Thu, 30 Mar 2006 13:18:08 +0000</pubDate>
		<guid isPermaLink="false">http://awads.net/wp/2006/03/30/the-q-quote-mechanism/#comment-3697</guid>
		<description>&lt;p&gt;For a simple example like this it hardly matters, but when you stat writing scripts that generate scripts, you can easily end up with loads of quotes, making it practically unreadable. In this situation, it can come in handy.&lt;/p&gt;

&lt;p&gt;Cheers&lt;/p&gt;

&lt;p&gt;Tim...&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>For a simple example like this it hardly matters, but when you stat writing scripts that generate scripts, you can easily end up with loads of quotes, making it practically unreadable. In this situation, it can come in handy.</p>
<p>Cheers</p>
<p>Tim&#8230;</p>
]]></content:encoded>
	</item>
</channel>
</rss>
