Вопрос: Гарантирует ли ORDER BY порядок вставки в таблицу?
Ответ: нет не гарантирует
НО есть маленькая особенность, если таблица содержит поле IDENTITY(!!!)
Если перенос данных делать через
SELECT Col1, Col2, ID=IDENTITY (int, 1, 1)
INTO NewTable
FROM OldTable
Order By Col1
То в разных ситуация может получиться разная картина, и даже так:
Col1 Col2 ID
------- -------- --------
1 A 4
2 Z 2
7 G 5
11 F 3
17 I 1
Если вставку делать в таблицу, которая создана заранее и содержит поле IDENTITY, то вставка:
INSERT INTO NewTable (Col1, Col2) SELECT Col1, Col2 FROM OldTable ORDER BY Col1
ГАРАНТИРУЕТ, что поле идентити будет следовать согласно полю по которому идёт сортировка
ID (identity) Col1 Col2
------------- ------ ------
1 1 S
2 2 z
3 7 G
4 11 F
5 17 I
Но это не гарантирует, опять же, физический порядок вставки. Вся особенность в том, что во втором случае значения поля идентити генерятся ДО самой вставки на базе условия ORDER BY.
ЗЫ: Печально, что в BOL это не описано, точнее убого описано и споров в форумах на эту тему нашёл больше, чем рассчитывал.
Ссылки по теме:
http://blogs.msdn.com/b/sqltips/archive/2005/07/20/441053.aspx
http://support.microsoft.com/kb/273586/en-us/
Спасибо Алексею Князеву за предоставленую информацию.
Данный блог, является записной книжкой. По работе приходится узнавать новые технологии, проводить тесты и сравнения, для хранения результатов решил создать данный блог дабы здесь выкладывать все свои находки и раскопки :)
Показаны сообщения с ярлыком MSSQL. Показать все сообщения
Показаны сообщения с ярлыком MSSQL. Показать все сообщения
среда, 26 января 2011 г.
суббота, 5 июня 2010 г.
Выполнение хронимых процедур MS SQL в JavaEE 6 (JSF2)
Возникла задача, выполнения хранимых процедур из базы MS SQL 2005 в коде моего проекта.
Долгое время бился над этим, но все-таки нащел решение.
Использовал:
NetBeans 9.2 RC2
JDBC MSQSQL version 3
Пример:
1. Класс сушности
2. Класс фасада
3. Класс предоставления данных (ViewEntity)
4. Вывод данных на экран
P.S: Заработало толька на GlassFishe который щел в комплекте с NetBeans 6.9 RC2
в остальных случиях шли непонятные ошибки.
не забывайте в процедурах писать SET NOCOUNT ON ;)
Тест выполняемой процедуры
PS: так как вывод быдет произведен 1 раз можно не писать SET NOCOUNT ON
Долгое время бился над этим, но все-таки нащел решение.
Использовал:
NetBeans 9.2 RC2
JDBC MSQSQL version 3
Пример:
1. Класс сушности
package model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.eclipse.persistence.annotations.Direction;
import org.eclipse.persistence.annotations.NamedStoredProcedureQuery;
import org.eclipse.persistence.annotations.StoredProcedureParameter;
@Entity
@NamedStoredProcedureQuery(name = "rpt_ret_test",
resultClass = MyEntity.class,
returnsResultSet = true,
procedureName = "rpt_ret_test",
parameters = {
@StoredProcedureParameter(name = "item",
queryParameter = "item", direction = Direction.IN, type = String.class)
})
public class MyEntity implements Serializable {
@Id
@Column(name = "item")
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}
2. Класс фасада
package controller;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import model.MyEntity;
@Stateless
public class MyEntityFacade {
@PersistenceContext(unitName = "ewqPU")
private EntityManager em;
public Listcustomize()
throws Exception {
try {
Query query = em.createNamedQuery("rpt_ret_test");
query.setParameter("item", "sdsds Мой тестовый параметр :)");
return query.getResultList();
} catch (Exception ex) {
throw ex;
}
}
}
3. Класс предоставления данных (ViewEntity)
package controller;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import model.MyEntity;
@ManagedBean(name = "MyEntityView")
@RequestScoped
public class MyEntityView {
@EJB
private MyEntityFacade myEntityFacade;
public ListgetMyEntityFacade() throws Exception {
return myEntityFacade.customize();
}
}
4. Вывод данных на экран
в xhtml через баловый вывод JSF Entity Data table
P.S: Заработало толька на GlassFishe который щел в комплекте с NetBeans 6.9 RC2
в остальных случиях шли непонятные ошибки.
не забывайте в процедурах писать SET NOCOUNT ON ;)
Тест выполняемой процедуры
Create Procedure dbo.RPT_RET_test (@Item NVARCHAR(50))
AS
BEGIN
SELECT @item
END
PS: так как вывод быдет произведен 1 раз можно не писать SET NOCOUNT ON
вторник, 25 мая 2010 г.
Начало работы с JSF 2
Вот небольшой список ссылок где можно найти полезную инфу о JSF 2 по мимо туториала :)
Поддержка JSF 2.0 в среде IDE NetBeans версии 6.8
Начало работы с приложениями Java EE 6
DevelopJavaEE6App
DevelopAjaxJSF2App
Java EE 6 Pet Catalog with GlassFish v3 preview and MySQL
JSF 2 fu, Part 2: Templating and composite components
http://www.ibm.com/developerworks/ru/library/0707_barcia/
This document had no style information.
ejb-local-ref
Document Information
Сушночти в JSF и Хронимые процедуры баз данных
Пример работы с Хронимыми процедурами от NetBeans
Презенташка от Sun по анатациям
Поддержка JSF 2.0 в среде IDE NetBeans версии 6.8
Начало работы с приложениями Java EE 6
DevelopJavaEE6App
DevelopAjaxJSF2App
Java EE 6 Pet Catalog with GlassFish v3 preview and MySQL
JSF 2 fu, Part 2: Templating and composite components
http://www.ibm.com/developerworks/ru/library/0707_barcia/
This document had no style information.
ejb-local-ref
Document Information
Сушночти в JSF и Хронимые процедуры баз данных
Пример работы с Хронимыми процедурами от NetBeans
Презенташка от Sun по анатациям
Старые CURSOR или новые WITH
Долгое время приходилось работать на SQL Server 2000 SP4. Также была необходимость сопровождать тот код что был написан до меня. После продолжительного времени работы мы перешли на SQL Server 2005 что открыло новые возможности и новый функционал. При его освоении начали переписывать старые наработки.
Задача:
Написать процедуру которая принемает параметр (Изделие item) и производит его разузловку (строит дерево вхождений)
Вопросы:
1. Как это делается ?
2. Есть ли смысл в переходе на нововведения ?
Парктика.
[SQL Server 2000] Что было в начале....
Альтернативный вариант, написан на SQL Server 2005
Как это делается показано выше, а вот есть ли смысл.....
Проводил тест на статичной базе (в базе работал только 1 пользователь) по изделию в который входит более 1500 вхождений.
Старые наработки [CURSOR] => выполнилось за 326 мс
Новый вариант [WITH] => выполнилось за 216 мс
В среднем прирост получается 33%
Статичной базе сильно незаметна выгода, а в активно рабочей базе прирост будет ощутим.
P.S.: Первый код (CURSOR) взят с рабочей базы и был изсправлен, в связи с этим
некоторые данные не совподают ;)
Со временем поправлю
Практика показала что если использовать WITH то Таблица которую он создает, может использоватся толька 1 раз. Либо ее необходимо поместить во временную таблюцу.
Задача:
Написать процедуру которая принемает параметр (Изделие item) и производит его разузловку (строит дерево вхождений)
Вопросы:
1. Как это делается ?
2. Есть ли смысл в переходе на нововведения ?
Парктика.
[SQL Server 2000] Что было в начале....
CREATE PROCEDURE [dbo].[MyProcSp] (@item NVARCHAR(255) = NULL)
AS
DECLARE @Col DECIMAL(10,5)
DECLARE @NowStartDate DATETIME
DECLARE @Item1 NVARCHAR(50)
DECLARE @pos SMALLINT
SET @NowStartDate = GETDATE()
IF OBJECT_ID('tempdb..#ItmTableTmp') IS NULL
BEGIN
CREATE TABLE #ItmTableTmp (item nvarchar(50)
, itemSub nvarchar(50)
, u_m nvarchar(3)
, Qty decimal(10,5)
, Level int
, P_M_T_Code nvarchar (1))
END
INSERT INTO #RET_STItem
SELECT @item, jm.item, i1.u_m, jm.matl_qty, @pos, i1.p_m_t_code
FROM item i
INNER JOIN job j ON (i.item=j.item) AND (i.job = j.job) AND (i.suffix = j.suffix) AND (j.type = 'S')
INNER JOIN jobmatl jm ON (jm.job = j.job) AND (jm.suffix = j.suffix)
INNER JOIN item i1 ON i1.item = jm.item
WHERE i.item = @item
AND jm.alt_group_rank = 0
ORDER BY jm.sequence
DECLARE @itemSub NVARCHAR(255)
DECLARE @posNext SMALLINT
DECLARE @p_m_t_code NVARCHAR(2)
SET @posNext=@pos+1
DECLARE c_cur CURSOR LOCAL STATIC FOR SELECT itemsub, qtyBase, p_m_t_code FROM #RET_STItem WHERE Level=@Pos and item=@item
OPEN c_cur
FETCH NEXT FROM c_cur INTO @itemSub,@Col,@p_m_t_code
WHILE @@Fetch_status=0
BEGIN
IF (DATEDIFF(mi, @NowStartDate, GETDATE()) < 31)
BEGIN
IF @p_m_t_code='M' EXEC [DBO].[RET_ShowStructItem1] @itemSub, @posNext,@Col
END
FETCH NEXT FROM c_cur INTO @itemSub,@Col,@p_m_t_code
END
CLOSE c_cur
DEALLOCATE c_cur
SELECT r.item
, i1.description
, r.QtyConst
, level
FROM #RET_STItem r
INNER JOIN item i ON i.item=r.itemsub
INNER JOIN item i1 ON i1.item=r.item
ORDER BY r.level, r.item, r.seq
Альтернативный вариант, написан на SQL Server 2005
CREATE PROCEDURE [dbo].[MyProcSp] (@item NVARCHAR(255) = NULL)
AS
DECLARE @pos SMALLINT
WITH RptOut (item, itemSub, u_m, Qty, Level, P_M_T_Code)
AS
(
-- Оригинал
SELECT i.item
, jm.item
, i1.u_m
, jm.qty
, rp.Level + 1
, i1.p_m_t_code
FROM item i
INNER JOIN job j ON (i.item=j.item) and (i.job=j.job) and (i.suffix=j.suffix) and (j.type='S')
INNER JOIN jobmatl jm ON (jm.job=j.job) and (jm.suffix=j.suffix)
INNER JOIN item i1 ON i1.item=jm.item
WHERE i.item=@item
AND jm.alt_group_rank = 0
UNION ALL
-- Рекурсия
SELECT i.item
, jm.item
, i1.u_m
, jm.qty
, rp.Level + 1
, i1.p_m_t_code
FROM item i
INNER JOIN job j ON (i.item=j.item) and (i.job=j.job) and (i.suffix=j.suffix) and (j.type='S')
INNER JOIN jobmatl jm ON (jm.job=j.job) and (jm.suffix=j.suffix)
INNER JOIN item i1 ON i1.item=jm.item
INNER JOIN RptOut rp ON rp.itemSub = i.item
WHERE jm.alt_group_rank = 0
)
SELECT * FROM RptOut
Как это делается показано выше, а вот есть ли смысл.....
Проводил тест на статичной базе (в базе работал только 1 пользователь) по изделию в который входит более 1500 вхождений.
Старые наработки [CURSOR] => выполнилось за 326 мс
Новый вариант [WITH] => выполнилось за 216 мс
В среднем прирост получается 33%
Статичной базе сильно незаметна выгода, а в активно рабочей базе прирост будет ощутим.
P.S.: Первый код (CURSOR) взят с рабочей базы и был изсправлен, в связи с этим
некоторые данные не совподают ;)
Со временем поправлю
Практика показала что если использовать WITH то Таблица которую он создает, может использоватся толька 1 раз. Либо ее необходимо поместить во временную таблюцу.
Подписаться на:
Сообщения (Atom)