Sending sql output to email body with conditional subject line

hi ,

i have written below piece of code to meet the requirement but i am stuck in the logic here.

the requirement are:
1) to send the sql out put to email body with proper formatting.
2) if count_matching = Yes then mail should triggered with the subject line as "load counts Match for 'yyyymmdd'
else
"warning : load_count mismatch for 'yyyymmdd'"

please provide any other alternate solution if any..

thanks in advance

=====================

#!/usr/bin/ksh

sqlplus -s abc/yaho12@xyz <<EOF
set feedback off trimspool on
set linesize 2000;
set newpage 0;
SET PAGESIZE 0;
set wrap on;
SET ECHO OFF;
SET HEADING OFF;
SET VERIFY OFF;
whenever sqlerror exit failure;
whenever oserror exit failure;
alter session enable parallel dml;
spool output.txt;
select 'load_DATE'  || '    ' ||
         'SOURCE_NAME'   || '    ' ||
         'COUNTS_MATCHING' 
from dual
union all
select load_DATE|| '               ' ||
       DL_SOURCE_NAME   || '            ' ||
       COUNTS_MATCHING 
from 
(SELECT        load_DATE,
                   SOURCE_NAME,
               CASE WHEN CNT1=CNT2 THEN 'Yes' ELSE 'No' END COUNTS_MATCHING
          FROM
         (
             select load_DATE,
                     SOURCE_NAME,
                   TABLE_ROW_COUNT AS CNT1,
                   INPUT_RECORD_CNT AS CNT2       
             from T1
             WHERE INSERT_DATE = TRUNC(SYSDATE)
         )
 );
spool off;
exit;
EOF


more output.txt | mail -s "load counts Match for $( date '+%d/%m/%Y' )" sk@xyz.com

=====================

To keep the forums high quality for all users, please take the time to format your posts correctly.

First of all, use Code Tags when you post any code or data samples so others can easily read your code. You can easily do this by highlighting your code and then clicking on the # in the editing menu. (You can also type code tags

```text
 and 
```

by hand.)

Second, avoid adding color or different fonts and font size to your posts. Selective use of color to highlight a single word or phrase can be useful at times, but using color, in general, makes the forums harder to read, especially bright colors like red.

Third, be careful when you cut-and-paste, edit any odd characters and make sure all links are working property.

Thank You.

The UNIX and Linux Forums

What do you mean by 'proper formatting'? What are you expecting and what do you get? To get strict formatting of text you may have to surround it with <pre>formatted text</pre> tags or send the email as an attachment.

The use of more especially may add newlines you didn't want. Just

<output.txt mail -s "load counts Match for $( date '+%d/%m/%Y' )"  sk@xyz.com

should be sufficient.

Or perhaps

( echo "<pre>" ; cat output.txt ; echo "</pre>" ) | mail -s "load counts Match for $( date '+%d/%m/%Y' )"  sk@xyz.com

(a rare useful use of cat on a single file).

Few more questions:

1) About the part of your logic in blue, did you mean:
a) Send an email with subject line: "warning: load counts mismatch for yyyymmdd" and the report as the email body, or
b) Do not send an email and just print "warning: ..." to stdout?

2) Will the part of your query in red return only one record?

  • If it returns 4 records and 2 of them have counts_matching = "Yes" and the other 2 have counts_matching = "No", then what should be the final value of counts_matching?

hi ,

thanks for reply . please let me know if more info is required,

1) About the part of your logic in blue, did you mean:
a) Send an email with subject line: "warning: load counts mismatch for yyyymmdd" and the report as the email body, or
b) Do not send an email and just print "warning: ..." to stdout? --no

--> in either case we need to send the report as the email body with the subject based on the output.

2) Will the part of your query in red return only one record? -- no , more than one record is also possible.

  • If it returns 4 records and 2 of them have counts_matching = "Yes" and the other 2 have counts_matching = "No", then what should be the final value of counts_matching?

--> in this case if all the counts_matching records = 'Yes' then subject line should be as "load counts Match for 'yyyymmdd' "
else if any of the counts_matching records = 'No' then subject line should be as ""warning : load_count mismatch for 'yyyymmdd'" but report should contain all the counts_matching records.

So, in order to determine the appropriate mail subject, you want to find out if all records had counts matching or not.

The following query returns 1 if all records inserted today in table t1 have identical values for table_row_count and input_record_cnt.
If at least one record has different values, then the query returns 0.

select case when sum(case when table_row_count = input_record_cnt then 1 else 0 end) = count(*)
            then 1 else 0
       end as x
  from t1
 where insert_date = trunc(sysdate);

Of course, I assume that all both these columns (table_row_count and input_record_cnt) have numeric datatype, integer values and are non-nullable.
If NULLs are involved, then things become complicated pretty quickly.

  • If one value is NULL and the other is, say, 5 then is that a mismatch or do you want to exclude them from comparison altogether, since NULL means "absence of value"?
  • If both values are NULLs then is that a match or a mismatch?
    Oracle has a lot of quirks regarding NULLs and I've avoided them in my suggested query.

Once you have this query, you can spool its output to another file and then read the said file to determine your mail subject.

Here's the shell script.
Note that I am echoing the mail command instead of executing it since I cannot email from my system.

$ 
$ 
$ cat -n generate_report.sh
     1	#!/usr/bin/ksh
     2	
     3	sqlplus -s user/pswd@db <<EOF
     4	set feedback off trimspool on
     5	set linesize 2000
     6	set newpage 0
     7	set pagesize 0
     8	set wrap on
     9	set echo off
    10	set verify off
    11	set time off timing off
    12	whenever sqlerror exit failure
    13	whenever oserror exit failure
    14	alter session enable parallel dml;
    15	spool output.txt
    16	SELECT 'LOAD_DATE SOURCE_NAME COUNTS_MATCHING'
    17	  FROM dual
    18	UNION ALL
    19	SELECT load_date || ' ' || source_name || ' ' ||
    20	       CASE WHEN table_row_count = input_record_cnt THEN 'Yes' ELSE 'No' END
    21	  FROM t1
    22	 WHERE insert_date = TRUNC(SYSDATE);
    23	spool off
    24	spool all_counts_match.txt
    25	select case when sum(case when table_row_count = input_record_cnt then 1 else 0 end) = count(*)
    26	            then 1 else 0
    27	       end as x
    28	  from t1
    29	 where insert_date = trunc(sysdate);
    30	spool off
    31	exit
    32	EOF
    33	
    34	if [[ $(cat all_counts_match.txt) -eq 1 ]]; then
    35	    mail_subject="Load counts match for $(date '+%d/%m/%Y')"
    36	else
    37	    mail_subject="Warning: Load counts do not match for $(date '+%d/%m/%Y')"
    38	fi
    39	echo "mail -s \"$mail_subject\" sk@xyz.com < output.txt"
    40	
$ 
$ 
$ . generate_report.sh
LOAD_DATE SOURCE_NAME COUNTS_MATCHING
01-JAN-17 SRC_1 Yes
01-FEB-17 SRC_2 Yes
01-MAR-17 SRC_3 Yes
	 1
mail -s "Load counts match for 13/03/2017" sk@xyz.com < output.txt
$ 
$ 
$ # After making a change in the data of the Oracle table so that the counts do not match...
$ 
$ . generate_report.sh
LOAD_DATE SOURCE_NAME COUNTS_MATCHING
01-JAN-17 SRC_1 Yes
01-FEB-17 SRC_2 No
01-MAR-17 SRC_3 Yes
	 0
mail -s "Warning: Load counts do not match for 13/03/2017" sk@xyz.com < output.txt
$ 
$ 

hi ,

thanks i am able to get the desired output but only issue is with the formatting below since the source_name length varies .

LOAD_DATE SOURCE_NAME COUNTS_MATCHING
01-JAN-17 SRC_14568        Yes
01-FEB-17 SRC_2322  Yes
01-MAR-17 SRC_334343443434 Yes

expected output
---------------------

LOAD_DATE SOURCE_NAME     COUNTS_MATCHING
01-JAN-17    SRC_14568                  Yes
01-FEB-17    SRC_2322                   Yes
01-MAR-17    SRC_334343443434           Yes

First of all - why aren't you using the "code" tags? The Moderator has reminded you two times and is doing the work that you should be doing.
Please have a look at the video in Post #2 and use "code" tags whenever you post your code.

Now about your formatting - the source_name length could vary, but it can never exceed the size of the (I guess) VARCHAR2 datatype. So you could use the RPAD function to pad blank spaces to all the columns. Unfortunately, this will have to be hard-coded as per your table structure.

Another option could be to use an appropriate value for the "colsep" sqlplus variable. By default, it is a blank space (" "). Set it something like "|" and then remove the concatenation operators from your query.

Post your attempted code with "code" tags if you get stuck.

Sorry i am new to his forum , will take care of CODE tag next time..

i tried below query using 'colsep' and got the correct formatting in the commandline but when i receive the same out put in email body the last column got jumbled again.

SET COLSEP "|"
SELECT 'LOAD_DATE SOURCE_NAME COUNTS_MATCHING'
FROM dual
    UNION ALL
SELECT load_date,source_name,(CASE WHEN table_row_count = input_record_cnt THEN 'Yes' ELSE 'No' END)
FROM t1
 WHERE insert_date = TRUNC(SYSDATE);

email body output
-------------------

20170314|SRC_OMNI           |No
20170314|SRC_CUST_EMAIL      |Yes
20170314|SRC_CONTACT_HIST         |Yes
20170314|SRC_RESPONSE_HIST         |Yes
20170314|SRC_USERNAME_ACCT_  |Yes

Your command-line has a monospaced font - maybe "Terminal" or Raster Fonts. Each character uses up the same amount of horizontal space, so the character "i" and "w" will be of equal width. Due to such fixed-width font, you see the output formatted properly.

Your email client, most likely, has a variable width font like, say, "Arial" or "Times New Roman". The character "i" will use up less space than the character "w". Hence the formatting gets disrupted.

If you select the text in your email client and set the font to, say, "Courier New" or "Consolas" or "Terminal" etc. then you will be able to see it properly formatted in your email body. Check the top menu items of your email program to see how the font of selected text can be changed.

1 Like
 If you select the text in your email client and set the font to, say, "Courier New" or "Consolas" or "Terminal" etc. then you will be able to see it properly formatted in your email body. Check the top menu items of your email program to see how the font of selected text can be changed.

.

Thanks for your valuable time.. i will look into this..i think it should work..

i have another query related to the same work flow..probably i will open a new thread for this..

thanks