динамический овал в оракуле [дубликат]

метаданные. Данные о ваших объектах / методах / свойствах.

Например, я могу объявить атрибут, называемый DisplayOrder, поэтому я могу легко контролировать, какие свойства порядка должны отображаться в пользовательском интерфейсе. Затем я мог бы добавить его в класс и написать некоторые компоненты графического интерфейса, которые извлекают атрибуты и упорядочивают элементы пользовательского интерфейса соответственно.

public class DisplayWrapper
{
    private UnderlyingClass underlyingObject;

    public DisplayWrapper(UnderlyingClass u)
    {
        underlyingObject = u;
    }

    [DisplayOrder(1)]
    public int SomeInt
    {
        get
        {
            return underlyingObject .SomeInt;
        }
    }

    [DisplayOrder(2)]
    public DateTime SomeDate
    {
        get
        {
            return underlyingObject .SomeDate;
        }
    }
}

Таким образом, гарантируя, что SomeInt всегда отображается перед SomeDate при работе с моими пользовательскими компонентами графического интерфейса .

Однако вы увидите их наиболее часто используемые вне среды прямого кодирования. Например, Windows Designer использует их широко, поэтому он знает, как обращаться с заказными объектами. Использование атрибута BrowsableAttribute следующим образом:

[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
    get{/*do something*/}
}

Сообщает разработчику не указывать это в доступных свойствах в окне свойств, например, во время разработки.

Вы могли также используют их для генерации кода, операций предварительной компиляции (например, Post-Sharp) или выполнения во время выполнения, таких как Reflection.Emit. Например, вы можете написать немного кода для профилирования, который прозрачно завершает каждый отдельный код, который делает ваш код, и время его. Вы можете «отказаться» от времени с помощью атрибута, который вы размещаете по определенным методам.

public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
    bool time = true;
    foreach (Attribute a in target.GetCustomAttributes())
    {
        if (a.GetType() is NoTimingAttribute)
        {
            time = false;
            break;
        }
    }
    if (time)
    {
        StopWatch stopWatch = new StopWatch();
        stopWatch.Start();
        targetMethod.Invoke(target, args);
        stopWatch.Stop();
        HandleTimingOutput(targetMethod, stopWatch.Duration);
    }
    else
    {
        targetMethod.Invoke(target, args);
    }
}

Объявление их просто, просто создайте класс, который наследуется от атрибута.

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

И помните, что когда вы используете этот атрибут, вы можете опустить атрибут суффикса, который компилятор добавит для вас.

8
задан prabhakar 19 March 2013 в 07:52
поделиться

6 ответов

Вы не можете поместить не константную строку в предложение IN предложения о свопинге. Вы можете использовать Pivot XML для этого.

Из documentation :

Подпрограмма

Подзапрос используется только в сочетании с ключевым словом XML. Когда вы указываете подзапрос, все значения, найденные подзапросом, используются для поворота

. Он должен выглядеть следующим образом:

select xmlserialize(content t.B_XML) from t_aa
pivot xml(
sum(A) for B in(any)
) t;

Вместо этого также может быть подзапрос ключевого слова ANY:

select xmlserialize(content t.B_XML) from t_aa
pivot xml(
sum(A) for B in (select cl from t_bb)
) t;

Вот демон sqlfiddle

8
ответ дан A.B.Cade 20 August 2018 в 16:25
поделиться
  • 1
    Привет, ваш метод работает фактически, но вывод я получаю в формате xml. могу ли я получить вывод в виде таблицы со строками и столбцами? – prabhakar 19 March 2013 в 09:45
  • 2
    AFAIK, не динамически ... Но как вы собираетесь использовать результат, который вы не знаете его структуры? – A.B.Cade 19 March 2013 в 10:09

ИСПОЛЬЗОВАТЬ ДИНАМИЧЕСКИЙ ЗАПРОС

Тестовый код ниже


--  DDL for Table TMP_TEST
--------------------------------------------------------

  CREATE TABLE "TMP_TEST" 
   (    "NAME" VARCHAR2(20), 
    "APP" VARCHAR2(20)
   );
/
SET DEFINE OFF;
Insert into TMP_TEST (NAME,APP) values ('suhaib','2');
Insert into TMP_TEST (NAME,APP) values ('suhaib','1');
Insert into TMP_TEST (NAME,APP) values ('shahzad','3');
Insert into TMP_TEST (NAME,APP) values ('shahzad','2');
Insert into TMP_TEST (NAME,APP) values ('shahzad','5');
Insert into TMP_TEST (NAME,APP) values ('tariq','1');
Insert into TMP_TEST (NAME,APP) values ('tariq','2');
Insert into TMP_TEST (NAME,APP) values ('tariq','6');
Insert into TMP_TEST (NAME,APP) values ('tariq','4');
/
  CREATE TABLE "TMP_TESTAPP" 
   (    "APP" VARCHAR2(20)
   );

SET DEFINE OFF;
Insert into TMP_TESTAPP (APP) values ('1');
Insert into TMP_TESTAPP (APP) values ('2');
Insert into TMP_TESTAPP (APP) values ('3');
Insert into TMP_TESTAPP (APP) values ('4');
Insert into TMP_TESTAPP (APP) values ('5');
Insert into TMP_TESTAPP (APP) values ('6');
/
create or replace PROCEDURE temp_test(
  pcursor out sys_refcursor,
    PRESULT                   OUT VARCHAR2
    )
AS
V_VALUES VARCHAR2(4000);
V_QUERY VARCHAR2(4000);
BEGIN
 PRESULT := 'Nothing';

-- concating activities name using comma, replace "'" with "''" because we will use it in dynamic query so "'" can effect query.
  SELECT DISTINCT 
         LISTAGG('''' || REPLACE(APP,'''','''''') || '''',',')
         WITHIN GROUP (ORDER BY APP) AS temp_in_statement 
    INTO V_VALUES
    FROM (SELECT DISTINCT APP 
            FROM TMP_TESTAPP);

-- designing dynamic query  

  V_QUERY := 'select * 
                from (  select NAME,APP 
                          from TMP_TEST   )   
               pivot (count(*) for APP in 
                     (' ||V_VALUES|| '))  
           order  by NAME' ;

    OPEN PCURSOR
     FOR V_QUERY;


 PRESULT := 'Success';

Exception
WHEN OTHERS THEN
 PRESULT := SQLcode || ' - ' || SQLERRM;
END temp_test;
1
ответ дан Rana Suhaib 20 August 2018 в 16:25
поделиться

Я не собираюсь давать ответ на вопрос, заданный OP, вместо этого я просто расскажу, как можно сделать динамический поворот.

Здесь мы должны использовать динамический sql, изначально извлекаем значения столбца в переменную и передачу переменной внутри динамического sql.

ПРИМЕР

. У нас есть таблица, как показано ниже.

Если нам нужно показать значения в столбце YR как имена столбцов и значения в этих столбцах из QTY, тогда мы можем использовать приведенный ниже код.

declare
  sqlqry clob;
  cols clob;
begin
  select listagg('''' || YR || ''' as "' || YR || '"', ',') within group (order by YR)
  into   cols
  from   (select distinct YR from EMPLOYEE);


  sqlqry :=
  '      
  select * from
  (
      select *
      from EMPLOYEE
  )
  pivot
  (
    MIN(QTY) for YR in (' || cols  || ')
  )';

  execute immediate sqlqry;
end;
/

RESULT

При необходимости вы также можете создать временную таблицу и выполнить запрос выбора в этой временной таблице, чтобы увидеть результаты. Его простое, просто добавьте CREATE TABLE TABLENAME AS в приведенный выше код.

sqlqry :=
'    
  CREATE TABLE TABLENAME AS
  select * from
0
ответ дан Sarath Avanavu 20 August 2018 в 16:25
поделиться

Для более поздних читателей здесь есть еще одно решение https://technology.amis.nl/2006/05/24/dynamic-sql-pivoting-stealing-antons-thunder/

, разрешающий запрос типа

select * from table( pivot(  'select deptno,  job, count(*) c from scott.emp group by deptno,job' ) )
4
ответ дан Scott 20 August 2018 в 16:25
поделиться

Вы не можете поместить динамический оператор в инструкцию PIVOT IN без использования PIVOT XML, который выводит несколько меньше желаемого результата. Тем не менее, вы можете создать строку IN и ввести ее в свой оператор.

Во-первых, вот моя таблица образцов;

  myNumber    myValue myLetter
---------- ---------- --------
         1          2 A        
         1          4 B        
         2          6 C        
         2          8 A        
         2         10 B        
         3         12 C        
         3         14 A      

Сначала настройте строку для использования в инструкции IN , Здесь вы помещаете строку в строку «str_in_statement». Мы используем COLUMN NEW_VALUE и LISTAGG для настройки строки.

clear columns
COLUMN temp_in_statement new_value str_in_statement
SELECT DISTINCT 
    LISTAGG('''' || myLetter || ''' AS ' || myLetter,',')
        WITHIN GROUP (ORDER BY myLetter) AS temp_in_statement 
    FROM (SELECT DISTINCT myLetter FROM myTable);

Ваша строка будет выглядеть так:

'A' AS A,'B' AS B,'C' AS C

Теперь используйте оператор String в вашем запросе PIVOT.

SELECT * FROM 
    (SELECT myNumber, myLetter, myValue FROM myTable)
    PIVOT (Sum(myValue) AS val FOR myLetter IN (&str_in_statement));

Вот вывод:

  MYNUMBER      A_VAL      B_VAL      C_VAL
---------- ---------- ---------- ----------
         1          2          4            
         2          8         10          6 
         3         14                    12 

Однако существуют ограничения. Вы можете конкатенировать строку до 4000 байт.

15
ответ дан user2179919 20 August 2018 в 16:25
поделиться
  • 1
    при попытке этого я получаю ниже ошибки оракула: ORA-56900: переменная привязки не поддерживается внутри оси pivot | операция univot – lourdh 22 April 2016 в 05:50
  • 2
    Как реализовать это в процедуре Oracle? PLS привести пример – Ram 2 February 2017 в 17:43

Я использовал вышеупомянутый метод (пользовательская функция Anton PL / SQL pivot ()), и он выполнил задание! Поскольку я не профессиональный разработчик Oracle, это простые шаги, которые я сделал:

1) Загрузите пакет zip, чтобы найти там pivotFun.sql. 2) Запустите один раз pivotFun.sql, чтобы создать новую функцию. 3) Используйте эту функцию в обычном SQL.

Просто будьте осторожны с именами динамических колонок. В моей среде я обнаружил, что имя столбца ограничено 30 символами и не может содержать в себе одну цитату. Итак, мой запрос теперь выглядит примерно так:

SELECT 
  *
FROM   
  table( 
        pivot('
                SELECT DISTINCT
                    P.proj_id,
                    REPLACE(substr(T.UDF_TYPE_LABEL, 1, 30), '''''''','','') as Attribute,
                    CASE
                      WHEN V.udf_text is null     and V.udf_date is null and      V.udf_number is NOT null  THEN to_char(V.udf_number)
                      WHEN V.udf_text is null     and V.udf_date is NOT null and  V.udf_number is null      THEN to_char(V.udf_date)
                      WHEN V.udf_text is NOT null and V.udf_date is null and      V.udf_number is null      THEN V.udf_text
                      ELSE NULL END
                    AS VALUE
                FROM
                    project   P
                LEFT JOIN UDFVALUE V ON P.proj_id     = V.proj_id 
                LEFT JOIN UDFTYPE  T ON V.UDF_TYPE_ID = T.UDF_TYPE_ID
                WHERE 
                    P.delete_session_id  IS NULL AND
                    T.TABLE_NAME = ''PROJECT''
    ')
)

Хорошо работает с записью до 1 м.

1
ответ дан user7144213 20 August 2018 в 16:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: