2013-05-17 1 views
1

У меня есть таблица в MS SQL Server, который выглядит как:Как передать переменную макроса PROC SQL заявление IN в ИНЕКЕ на MS SQL Server

ID, Code 
01, A 
02, A 
03, B 
04, C 
... 

и определяется в SAS, как

LIBNAME MSSQLDB ODBC 
    CONNECTION=SHAREDREAD 
    COMPLETE='Description=OIPE DW (Dev);DRIVER=SQL Server Native Client 11.0;SERVER=Amazon;Trusted_Connection=Yes;DATABASE=OIPEDW_Dev;' 
    SCHEMA='dbo' 
    PRESERVE_TAB_NAMES=YES 
    PRESERVE_COL_NAMES=YES; 

У меня есть набор данных SAS, который имеет записи того же формата, что и MSSQLDB (идентификаторы и переменные кода), но является всего лишь подмножеством полной базы данных.

Я хотел бы сделать следующее:

PROC SQL NOPRINT; 
    /* If SASDS contains just codes A and B, CodeVar=A B 
    SELECT DISCTINCT CODE INTO :CodeVar SEPARATED BY ' ' FROM SASDS; 
QUIT; 
/* seplist is a macro that wraps each code in a quote */ 
%LET CodeInVar=%seplist(&CodeVar, nest=%STR(")); 
PROC SQL; 
    DELETE * FROM MSSQLDB WHERE CODE IN (&CodeInVar); 
    /* Should execute DELETE * FROM MSSQL WHERE CODE IN ('A','B'); 
QUIT; 

Проблема заключается в следующем генерирует синтаксическую ошибку на значениях макропеременной & CodeInVar.

Любая идея передать значение макропеременной для SQL Server в инструкции IN?

ответ

2

Я думаю, у вас здесь несколько проблем; надеюсь, некоторые из них являются просто ошибками транскрипции.

Во-первых, это не будет делать ничего:

PROC SQL; 
    DELETE * FROM MSSQLDB WHERE CODE IN (&CodeInVar); 
    /* Should execute DELETE * FROM MSSQL WHERE CODE IN ('A','B'); 
QUIT; 

MSSQLDB твой Имя_библиотеки, не таблица; вам нужно определить его как MSSQLDB.dbname здесь. Возможно, это просто ошибка копирования.

По сути, нет ничего явно неправильного в том, что вы набрали. Я бы предложил сначала определить, есть ли какие-либо проблемы с вашей макропеременной. Положите там заявление% put:

%put &codeinvar.; 

Посмотрите, что выйдет. Это то, что вы хотели? Если нет, тогда исправьте эту часть (предположительно, макрос).

Я бы сказал, что есть много лучших способов сделать это. Во-первых, вам не нужно добавлять макрос для добавления запятых или кавычек или чего-либо еще.

PROC SQL NOPRINT; 
    /* If SASDS contains just codes A and B, CodeVar=A B */ 
    SELECT DISCTINCT cats("'",CODE,"'") INTO :CodeVar SEPARATED BY ',' FROM SASDS; 
QUIT; 

Это должно помочь вам & codevar именно так, как вы хотите [т.е. 'A','B'].

Во-вторых, поскольку вы используете LIBNAME и не выполняете SQL, лучше используйте синтаксис SQL, а не полностью.

proc sql; 
delete from MSSQLDB.yourtable Y where exists 
    (select 1 from SASDS S where S.code=Y.code); 
quit; 

Это происходит быстрее, в зависимости от обстоятельств (это также может быть медленнее). Если код - это то, что имеет высокую частоту, сначала суммируйте его, используя PROC FREQ или SQL-запрос.

+1

Вы имеете право на ошибку транскрипции. Кроме того, спасибо за предложение о создании строки без макроса. Наконец, я сделал в основном то, что вы предложили в конце, и переместил оператор select в инструкцию IN, и это сработало. Благодаря! – dmonder

+0

Я добавляю комментарий, поскольку я не мог найти этот ответ нигде. 1. Используйте CATS ("'", имя столбца, "'") для создания макропеременной, удерживающей «значения». 2. Вам, вероятно, не нужно использовать макро переменную. Вместо этого просто выберите список имен в качестве подзапроса в основном запросе. – psychonomics

 Смежные вопросы

  • Нет связанных вопросов^_^