MVC дает Вам, больше управления Вашим выводом, и с тем управлением происходит больший риск записи плохо разработанного HTML, супа тега, и т.д.
, Но в то же время у Вас есть несколько новых опций, которые Вы не имели прежде...
Теперь но это вовсе не значит, что Вы не можете сделать, любая из этих вещей с WebForms, но MVC облегчает.
я все еще использую WebForms для того, когда я должен быстро создать веб-приложение, так как я могу использовать в своих интересах управление сервером и т.д. WebForms скрывает все подробности входных тегов и кнопок отправки.
И WebForms и MVC способны к абсолютному мусору, если Вы небрежны. Как всегда, тщательное планирование и хорошо продумал дизайн, приведет к качественному приложению, независимо если это будет MVC или WebForms.
[Обновление]
, Если это - какое-либо утешение также, MVC является просто новой, развивающейся технологией от Microsoft. Было много регистраций, которыми WebForms не только останется, но продолжит разрабатываться для...
... и так далее...
Для обеспокоенных маршрутом MVC берет, я предложил бы дать "парням" Вашу обратную связь. Они, кажется, слушают до сих пор!
Oracle
ведет себя не так, как другие системы. Oracle
имеет множество преимуществ перед другими СУБД
, но они не являются темой сообщения. Вы не можете SELECT
без FROM
.
ВЫБОР 1
завершится ошибкой, вам необходимо:
ВЫБРАТЬ 1
ОТ двойного
Пустая строка и NULL
- это одно и то же.
SELECT *
ОТ двойного
ГДЕ '' = ''
ничего не возвращает.
Нет ни TOP
, ни LIMIT
. Вы ограничиваете свои результаты предложением WHERE
:
SELECT *
ОТ (
ВЫБРАТЬ *
ИЗ mytable
СОРТИРОВАТЬ ПО
Col
)
ГДЕ rownum <10
именно так, используя подзапрос, поскольку ROWNUM
вычисляется перед ORDER BY
.
Вы не можете вложить коррелированные подзапросы глубже, чем на один уровень. Это не удастся:
SELECT (
ВЫБРАТЬ *
ОТ (
ВЫБЕРИТЕ манекен
ОТ двойного ди
ГДЕ di.dummy = do.dummy
СОРТИРОВАТЬ ПО
манекен
)
ГДЕ rownum = 1
)
От двойного делать
Это проблема.
NULL
значения не индексируются. Этот запрос не будет использовать индекс для упорядочивания:
SELECT *
ОТ (
ВЫБРАТЬ *
ИЗ mytable
СОРТИРОВАТЬ ПО
Col
)
ГДЕ rownum <10
, если столбец
не отмечен как NOT NULL
.
Обратите внимание, что это NULL
значения , которые не индексируются, а не столбцы . Вы можете создать индекс для столбца, допускающего значение NULL, и значения, отличные от NULL
, попадут в индекс.
Однако индекс не будет использоваться, если условие запроса предполагает, что NULL
] значения могут удовлетворить его.
В приведенном выше примере вы хотите, чтобы возвращалось все значение (включая NULL
s). Тогда index не знает значений, отличных от NULL
, и, следовательно, не может их получить.
SELECT *
ОТ (
ВЫБРАТЬ *
ИЗ mytable
СОРТИРОВАТЬ ПО
Col
)
ГДЕ rownum <10
Но этот запрос будет использовать индекс:
SELECT *
ОТ (
ВЫБРАТЬ *
ИЗ mytable
ГДЕ col НЕ ПУСТО
СОРТИРОВАТЬ ПО
Col
)
ГДЕ rownum <10
, поскольку значения, отличные от NULL
, никогда не могут удовлетворять условию.
По умолчанию, NULL
сортируются последними, а не первыми (как в PostgreSQL
], но в отличие от MySQL
и SQL Server
)
Этот запрос:
SELECT *
ОТ (
ВЫБРАТЬ 1 КАК id
ОТ двойного
СОЮЗ ВСЕ
ВЫБРАТЬ NULL КАК id
ОТ двойного
) q
СОРТИРОВАТЬ ПО
Я бы
вернет
идентификатор
---
1
ЗНАЧЕНИЕ NULL
Для сортировки, как в SQL Server
и MySQL
, используйте следующее:
SELECT *
ОТ (
ВЫБРАТЬ 1 КАК id
ОТ двойного
СОЮЗ ВСЕ
ВЫБРАТЬ NULL КАК id
ОТ двойного
) q
СОРТИРОВАТЬ ПО
id NULLS FIRST
Обратите внимание, что он нарушает порядок rownum
, если последний не используется вне подзапроса (как описано выше)
«MYTABLE»
и «mytable»
( двойные кавычки имеют значение) - это разные объекты.
SELECT *
ИЗ mytable - без цитат
выберет из первого, а не из второго. Если первого не существует, запрос завершится ошибкой.
CREATE TABLE mytable
создает «MYTABLE»
, а не «mytable»
.
В Oracle
все неявные блокировки (которые являются результатом DML
] операции) находятся на уровне строк и никогда не расширяются. Это означает, что никакая строка, на которую не влияет транзакция, не может быть неявно заблокирована.
Писатели никогда не блокируют считыватели (и наоборот).
Чтобы заблокировать всю таблицу, вы должны выпустить явный оператор LOCK TABLE
.
Блокировки строк хранятся на страницах данных.
В Oracle
нет « CLUSTERED
индексов», есть «упорядоченные по индексам таблицы». По умолчанию таблицы организованы в виде кучи (в отличие от SQL Server
и MySQL
с InnoDB
).
В Oracle
мире существует " означает организацию нескольких таблиц таким образом, чтобы строки с общим ключом (из нескольких таблиц) также имели общую страницу данных.
На одной странице данных размещается несколько строк из нескольких таблиц, что делает соединения по этому ключу очень быстрыми.
ВЫБРАТЬ 1 не работает, вместо этого выберите 1 из двойного.
Если вы работаете с иерархическими данными, отлично подходит подключение через.
Один комментарий: вам не нужно создавать триггер для использования последовательностей, если вы не твердо намерены реплицировать поведение столбца Sybase / SQL Server IDENTITY. Я считаю более полезным просто использовать последовательность непосредственно в фактических операторах вставки, например
INSERT
INTO MyTable
( KeyCol
, Name
, Value
)
SELECT Seq_MyTable.NextVal
, 'some name'
, 123
FROM dual;
. Вам не нужно беспокоиться о накладных расходах на выполнение триггера, и у вас есть гибкость для вставки строк в таблицу без необходимости беспокоиться о присвоении значений последовательности (например, при перемещении данных из схемы в другую). Вы также можете предварительно выбрать значения из последовательности для вставки диапазонов данных и других методов, которые функция IDENTITY делает затруднительными или невозможными.
Не забудьте использовать nvl (столбец) вокруг любого столбца в наборе строк, который может быть заполнен полностью с нулевыми значениями. В противном случае столбец будет отсутствовать в наборе строк.
Верно, отсутствует полностью!
Пример:
SELECT nvl(employeeName,'Archie'), nvl(employeeSpouse,'Edith') FROM Employee
Это гарантирует, что вы получите два столбца в наборе строк, даже если все значения в обоих равны нулю. Вы просто увидите кучу значений «Арчи» и «Эдит». Если вы не используете nvl (), вы потенциально можете получить только один столбец или ни одного обратно. Важная часть этого заключается в том, что ваш код может нормально работать в вашей среде разработки и даже проходить контроль качества, но когда он попадает в производство,
Кажется, я столкнулся с большим количеством баз данных Oracle, чувствительных к регистру объектов схемы и данных, чем в SQL Server .
Здесь я описал несколько отличий: Думаете, стандартный SQL ANSI полностью переносится между базами данных? Подумайте еще раз.
Временные таблицы
Вы создаете и индексируете их, как обычные таблицы, но каждая сессия / транзакция видит только свои собственные данные. Это отличается от MS SQL.
Глобальные переменные
Они передаются по ссылке. Это означает, что если вы передадите глобальную переменную в процедуру в качестве параметра и измените глобальную переменную внутри вашей процедуры, значение параметра также изменится. Однако не очень популярный метод.
Триггеры
До самых последних версий не было способа определить способ срабатывания подобных триггеров. Если вас действительно волновало, какое из «ПЕРЕД ОБНОВЛЕНИЕМ ДЛЯ КАЖДОЙ СТРОКИ» было первым, вы помещаете все это в один триггер.
Нет объединения групп, как в MySQL. Если вам нужна агрегатная функция объединения групп, вы должны написать свою собственную. Вот моя реализация:
drop type T_GROUP_CONCAT;
create or replace type GROUP_CONCAT_PARAM as object
(
val varchar2(255),
separator varchar2(10),
numToConcat NUMBER,
MAP MEMBER FUNCTION GROUP_CONCAT_PARAM_ToInt return VARCHAR2
);
--map function needed for disctinct in select clauses
CREATE OR REPLACE TYPE BODY GROUP_CONCAT_PARAM IS
MAP MEMBER FUNCTION GROUP_CONCAT_PARAM_ToInt return VARCHAR2 is
begin
return val;
end;
end;
/
CREATE OR REPLACE TYPE T_GROUP_CONCAT
AS OBJECT (
runningConcat VARCHAR2(5000),
runningCount NUMBER,
STATIC FUNCTION ODCIAggregateInitialize
( actx IN OUT T_GROUP_CONCAT
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate
( self IN OUT T_GROUP_CONCAT,
val IN GROUP_CONCAT_PARAM
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate
( self IN T_GROUP_CONCAT,
returnValue OUT VARCHAR2,
flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge
(self IN OUT T_GROUP_CONCAT,
ctx2 IN T_GROUP_CONCAT
) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY T_GROUP_CONCAT AS
STATIC FUNCTION ODCIAggregateInitialize
( actx IN OUT T_GROUP_CONCAT
) RETURN NUMBER IS
BEGIN
IF actx IS NULL THEN
actx := T_GROUP_CONCAT ('', 0);
ELSE
actx.runningConcat := '';
actx.runningCount := 0;
END IF;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateIterate
( self IN OUT T_GROUP_CONCAT,
val IN GROUP_CONCAT_PARAM
) RETURN NUMBER IS
BEGIN
if self.runningCount = 0 then
self.runningConcat := val.val;
elsif self.runningCount < val.numToConcat then
self.runningConcat := self.runningConcat || val.separator || val.val;
end if;
self.runningCount := self.runningCount + 1;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateTerminate
( self IN T_GROUP_CONCAT,
ReturnValue OUT VARCHAR2,
flags IN NUMBER
) RETURN NUMBER IS
BEGIN
returnValue := self.runningConcat;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateMerge
(self IN OUT T_GROUP_CONCAT,
ctx2 IN T_GROUP_CONCAT
) RETURN NUMBER IS
BEGIN
self.runningConcat := self.runningConcat || ',' || ctx2.runningConcat;
self.runningCount := self.runningCount + ctx2.runningCount;
RETURN ODCIConst.Success;
END;
END;
/
CREATE OR REPLACE FUNCTION GROUP_CONCAT
( x GROUP_CONCAT_PARAM
) RETURN VARCHAR2
--PARALLEL_ENABLE
AGGREGATE USING T_GROUP_CONCAT;
/
Чтобы использовать:
select GROUP_CONCAT(GROUP_CONCAT_PARAM(tbl.someColumn, '|', 2)) from someTable tbl