BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
pchegoor
Pyrite | Level 9

Hello All,


I am updating a SQL server Table called sml_emp_exp_rpt (Master) using a SAS
Dataset called all_renewals (Transaction).Both the Master and Transaction tables have

fields grpmain and rnwl_dt.


The Master table can have more than one record for the combination of
grpmain and rnwl_dt  fields from Transaction table and all such records need to be
updated in the master Table using the Information from transaction table.The Transaction table
has only one record for a grpmain and rnwl_dt combination.Also all
combinations of grpmain and rnwl_dt in the Master table are also present in
the Transaction table.


So i am using the below code to update 4 columns in the Master table using
the transaction table.This method works ,however is very slow and right now
takes about 35 mins to update 133K records in the Master table.


Here is my SAS Code:

/*********************************************************************************************************/


libname sql_sgr SQLSVR user=user1 password=pwd1 datasrc=testpath;
libname sm_grp '/shrproj/files/sas_data/sm_grp';


proc sql;
create table all_renewals as
Select    distinct grpmain,
             datepart(rnwl_dt) as rnwl_dt,
             agency,
             agency_agent,
             mkt_rep,
             rnwl_status_cd
from sm_grp.be_ALL_RENEWALS
;
quit;


proc sql;
update sql_sgr.sml_emp_exp_rpt a
set agency=(select b.agency
                   from all_renewals as b
                  where a.rnwl_dt=b.rnwl_dt
                  and a.grpmain=b.grpmain),
  agency_agent=(select b.agency_agent
                   from all_renewals as b
                 where a.rnwl_dt=b.rnwl_dt
                 and a.grpmain=b.grpmain),
  MRKT_REP_ID=(select b.mkt_rep
                 from all_renewals as b
                where a.rnwl_dt=b.rnwl_dt
                and a.grpmain=b.grpmain),
  rnwl_status_cd=(select b.rnwl_status_cd
                 from all_renewals as b
               where a.rnwl_dt=b.rnwl_dt
               and a.grpmain=b.grpmain)
;
quit

/***************************************************************************************************/


My question is how can the above Code be modified to Improve the Efficiency
of the Update?


Please let me know of any Solution.

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
DBailey
Lapis Lazuli | Level 10

Agree w/ LinusH.  Create an "input" table then merge the two.  You might include the insertbuff option as well to speed up the inserts.  Bulk loading might be a possibility but I've never been able to get it to work for Sqlserver.

libname sql_sgr SQLSVR user=user1 password=pwd1 datasrc=testpath insertbuff = 10000;

libname sm_grp '/shrproj/files/sas_data/sm_grp';


proc sql;

connect to SQLSVR as cSQL (user=user1 password=pwd1 datasrc=testpath insertbuff = 10000);


create table sql_sgr.tmp as

Select    distinct grpmain,

             datepart(rnwl_dt) as rnwl_dt,

             agency,

             agency_agent,

             mkt_rep,

             rnwl_status_cd

from sm_grp.be_ALL_RENEWALS


execute (

     merge into sml_emp_exp_rpt a

     using tmp b

          on (a.rnwl_dt=b.rnwl_dt

                  and a.grpmain=b.grpmain)

     when matched then update

          set

               a.agency=b.agency,

               a.agency_agent=b.agency_agent,

               a.mkt_rep=b.mkt_rep,

               a.mwl_status_cd=b.mwl_status_cd

) by cSQL;


execute (drop table tmp) by cSQL;


disconnect from cSQL;

quit;

check merge statement syntax

View solution in original post

5 REPLIES 5
LinusH
Tourmaline | Level 20

I like SQL a lot, but for certain kind of updates, it's terrible...

How large is your Master table?

If you have the appropriate rights, it could probably be more efficient to extract the whole table to SAS, update it using  a data step, truncate the original in SQL Server, and bulk load it back.

Another option is to upload you transactions as a temporary tabel to SQL Server, and then perhaps you'll get a implicit SQL pass-thru of the update operations (use options sastrace=',,,d' sastraceloc=saslog; to verify), or use explicit SQL pass-thru to make sure that all update processing will take place in SQL Server.

Data never sleeps
DBailey
Lapis Lazuli | Level 10

Agree w/ LinusH.  Create an "input" table then merge the two.  You might include the insertbuff option as well to speed up the inserts.  Bulk loading might be a possibility but I've never been able to get it to work for Sqlserver.

libname sql_sgr SQLSVR user=user1 password=pwd1 datasrc=testpath insertbuff = 10000;

libname sm_grp '/shrproj/files/sas_data/sm_grp';


proc sql;

connect to SQLSVR as cSQL (user=user1 password=pwd1 datasrc=testpath insertbuff = 10000);


create table sql_sgr.tmp as

Select    distinct grpmain,

             datepart(rnwl_dt) as rnwl_dt,

             agency,

             agency_agent,

             mkt_rep,

             rnwl_status_cd

from sm_grp.be_ALL_RENEWALS


execute (

     merge into sml_emp_exp_rpt a

     using tmp b

          on (a.rnwl_dt=b.rnwl_dt

                  and a.grpmain=b.grpmain)

     when matched then update

          set

               a.agency=b.agency,

               a.agency_agent=b.agency_agent,

               a.mkt_rep=b.mkt_rep,

               a.mwl_status_cd=b.mwl_status_cd

) by cSQL;


execute (drop table tmp) by cSQL;


disconnect from cSQL;

quit;

check merge statement syntax

pchegoor
Pyrite | Level 9

Thanks LinusH and DBailey  i used the above suggested method and it worked. This is what i did :

proc sql;

connect to SQLSVR (user=&sql_user_id. password="&sql_password." datasrc=&sql_path. insertbuff = 10000);

create table sql_sgr.all_renewals as

Select    distinct grpmain,

datepart(rnwl_dt) as rnwl_dt format=date9.,

agency,

agency_agent,

mkt_rep,

rnwl_status_cd

from sm_grp.be_ALL_RENEWALS;

execute (

     merge into sml_emp_exp_rpt a

     using all_renewals b

          on (a.rnwl_dt=b.rnwl_dt

                  and a.grpmain=b.grpmain)

     when matched then update

          set

               a.agency=b.agency,

               a.agency_agent=b.agency_agent,

               a.mrkt_rep_id=b.mkt_rep,

               a.rnwl_status_cd=b.rnwl_status_cd;

) by SQLSVR;

execute (drop table all_renewals) by SQLSVR;

disconnect from SQLSVR;

quit;

Now it takes only about 5 secs to update 135559  rows of the sql server table.


sasuser77
Calcite | Level 5

 

is it specific to SQL Server. I am having difficult making it work on Access database. 

 

ERROR: Execute: Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or
'UPDATE'.

SASKiwi
PROC Star

MS Access SQL is different to SQL Server SQL, Search the SAS Support site for examples of updating MS Access. If you are still stuck, create a new post. Adding to an existing post for a different problem is unlikely to be helpful.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 7548 views
  • 3 likes
  • 5 in conversation