Parameters SAS的宏参数中会丢失换行符
我想将包含换行符的文本从SAS表传输到外部数据库表(通过ODBC)。 我使用宏变量作为缓冲区。我使用宏将文本插入表中 远程数据库的。问题是文本中的换行符丢失了, 如果我将文本作为参数传递给宏。 我怎样才能保持线路中断Parameters SAS的宏参数中会丢失换行符,parameters,sas,macros,Parameters,Sas,Macros,我想将包含换行符的文本从SAS表传输到外部数据库表(通过ODBC)。 我使用宏变量作为缓冲区。我使用宏将文本插入表中 远程数据库的。问题是文本中的换行符丢失了, 如果我将文本作为参数传递给宏。 我怎样才能保持线路中断 %macro dbinsert (id=,text=); /* Macro for inserting text into table of second database. For test purposes, odbc table replaced with SAS
%macro dbinsert (id=,text=);
/*
Macro for inserting text into table of second database.
For test purposes, odbc table replaced with SAS table.
Issue: line breaks will be lost. How can i keep the line breaks?
Original Code:
proc sql;
CONNECT TO ODBC (DSN="mydb");
EXEC (update mytable
set text= "&text."
where id = &id.;
) BY ODBC;
quit;
*/
proc sql noprint;
update x2
set text = "&text."
where id = &id.;
quit;
%mend dbinsert;
%macro main;
/* Initialize SAS table. Just for test purposes. */
data x1;
text="Hello Martin how are you?"; output;
text="Thank you I am fine!"; output;
text="And how are you?"; output;
run;
/* Read content from SAS table into macro variable (text1). The content is separated via line breaks 0D0A. */
proc sql noprint;
select text into :text1 separated by '0D0A'x from x1;
quit;
/* Initialize table in second database. Just for test purposes. */
data x2;
length id 8 text $200;
id=1; text="111"; output;
id=2; text="222"; output;
run;
%dbinsert(id=2,text=&text1.);
%mend main;
%main;
宏不支持不可打印的字符
data _null_;
call symputx('text',quote(symget('text'),"'"));
run;
从文件
…
SAS宏语言是一种基于字符串的语言。它不支持使用十六进制字符常量
注意:SAS宏语言不支持使用十六进制值指定不可打印的字符。
及
…
宏变量值的最大长度为65534个字符。宏变量的长度由指定给它的文本决定,而不是由特定的长度声明决定。因此,它的长度随包含的每个值而变化。宏变量只包含字符数据。但是,宏工具具有一些功能,当变量包含可解释为数字的字符数据时,可以将其作为数字进行计算。宏变量的值将保持不变,直到具体更改为止。宏变量独立于SAS数据集变量
注意:只能将可打印字符指定给宏变量。分配给宏变量的不可打印值可能导致不可预测的结果。
可能的替代方案 你知道EXEC和pass-through,很好 考虑使用SQL为串联字符串文字的字符串表达式构建源代码。表达式将包含使用远程数据库本机字符函数的源代码。必须修改
DBINSERT
宏以处理现在包含表达式的参数
同样,宏会将不可打印的字符转换为空格,因此如果x1.text
中的数据值包含嵌入的CRLF,则它们不会出现在构造的表达式中
例如:
重要提示:请勿将此版本的DBINSERT与不受信任的用户提供的任何输入或WEB输入一起使用。来自数据值的Codegen是SQL注入或代码注入的向量
%macro dbinsert (id=,expression=);
proc sql noprint;
update x2
set text = &expression
where id = &id.;
quit;
%mend dbinsert;
data x1;
text="Hello Martin how are you?"; output;
text="Thank you I am fine!"; output;
text="And how are you?"; output;
run;
/*
* CONSTRUCT SOURCE CODE FOR AN EXPRESSION THAT CONCATENTATES STRING LITERALS
* (also known as codegen short for code generator)
*/
proc sql noprint;
select
quote(trim(text))
into :text1
separated by '||byte(13)||byte(10)||'
from x1;
data x2;
length id 8 text $200;
id=1; text="111"; output;
id=2; text="222"; output;
run;
options mprint;
%dbinsert(id=2,expression=&text1.);
%symdel text1;
title;
ods html style=monospace;
proc print data=x2; where id=2;
proc print data=x2; where id=2; format text $HEX400.;
proc print data=x2; where id=2;
var text / style=[asis=true];
run;
ods html close;
调用DBINSERT
时显示codegen运行的日志
634 %dbinsert(id=2,expression=&text1.);
MPRINT(DBINSERT): proc sql noprint;
MPRINT(DBINSERT): update x2 set text = "Hello Martin how are you?"||byte(13)||byte(10)||"Thank
you I am fine!"||byte(13)||byte(10)||"And how are you?" where id = 2;
NOTE: 1 row was updated in WORK.X2.
检查结果。SAS ViewTable将不可打印的内容呈现为空格,但控制字符位于数据值中
在查看器中显示结果的图像
在ODS HTML中的结果相同,第二个表显示十六进制格式时的文本值。第三个表显示了当样式选项ASIS=YES
生效时,查看由ODS HTML
解释的控制字符
宏不支持不可打印的字符
data _null_;
call symputx('text',quote(symget('text'),"'"));
run;
从文件
…
SAS宏语言是一种基于字符串的语言。它不支持使用十六进制字符常量
注意:SAS宏语言不支持使用十六进制值指定不可打印的字符。
及
…
宏变量值的最大长度为65534个字符。宏变量的长度由指定给它的文本决定,而不是由特定的长度声明决定。因此,它的长度随包含的每个值而变化。宏变量只包含字符数据。但是,宏工具具有一些功能,当变量包含可解释为数字的字符数据时,可以将其作为数字进行计算。宏变量的值将保持不变,直到具体更改为止。宏变量独立于SAS数据集变量
注意:只能将可打印字符指定给宏变量。分配给宏变量的不可打印值可能导致不可预测的结果。
可能的替代方案 你知道EXEC和pass-through,很好 考虑使用SQL为串联字符串文字的字符串表达式构建源代码。表达式将包含使用远程数据库本机字符函数的源代码。必须修改
DBINSERT
宏以处理现在包含表达式的参数
同样,宏会将不可打印的字符转换为空格,因此如果x1.text
中的数据值包含嵌入的CRLF,则它们不会出现在构造的表达式中
例如:
重要提示:请勿将此版本的DBINSERT与不受信任的用户提供的任何输入或WEB输入一起使用。来自数据值的Codegen是SQL注入或代码注入的向量
%macro dbinsert (id=,expression=);
proc sql noprint;
update x2
set text = &expression
where id = &id.;
quit;
%mend dbinsert;
data x1;
text="Hello Martin how are you?"; output;
text="Thank you I am fine!"; output;
text="And how are you?"; output;
run;
/*
* CONSTRUCT SOURCE CODE FOR AN EXPRESSION THAT CONCATENTATES STRING LITERALS
* (also known as codegen short for code generator)
*/
proc sql noprint;
select
quote(trim(text))
into :text1
separated by '||byte(13)||byte(10)||'
from x1;
data x2;
length id 8 text $200;
id=1; text="111"; output;
id=2; text="222"; output;
run;
options mprint;
%dbinsert(id=2,expression=&text1.);
%symdel text1;
title;
ods html style=monospace;
proc print data=x2; where id=2;
proc print data=x2; where id=2; format text $HEX400.;
proc print data=x2; where id=2;
var text / style=[asis=true];
run;
ods html close;
调用DBINSERT
时显示codegen运行的日志
634 %dbinsert(id=2,expression=&text1.);
MPRINT(DBINSERT): proc sql noprint;
MPRINT(DBINSERT): update x2 set text = "Hello Martin how are you?"||byte(13)||byte(10)||"Thank
you I am fine!"||byte(13)||byte(10)||"And how are you?" where id = 2;
NOTE: 1 row was updated in WORK.X2.
检查结果。SAS ViewTable将不可打印的内容呈现为空格,但控制字符位于数据值中
在查看器中显示结果的图像
在ODS HTML中的结果相同,第二个表显示十六进制格式时的文本值。第三个表显示了当样式选项ASIS=YES
生效时,查看由ODS HTML
解释的控制字符
不必尝试添加将宏变量的值转换为有效代码所需的引号,只需编写宏,假设该值已经是要包含在生成代码中的有效语法即可。那么SQL语法就是:
set text = &text.
然后,如果需要添加远程系统用于在字符串中指定特殊字符的任何语法,您可以使用
%dbinsert (id=,text='ABC'||byte(13)||'XYZ')
如果您有一个现有的宏变量,并且希望将其括在单引号中,则可以使用数据步骤来保留任何特殊字符