Équivalent du RowID D'Oracle dans SQL Server
13 réponses
pseudo-colonne ROWID
pour chaque ligne de la base de données, la pseudocolumn ROWID renvoie la l'adresse de la ligne. Les valeurs rowid de la base de données Oracle contiennent des informations nécessaire pour localiser une rangée:
- le numéro d'objet de données de l'objet
- Le bloc de données dans la fichier de données dans laquelle la ligne réside
- la position de la rangée dans le bloc de données (la première rangée est 0)
- le fichier de données dans lequel la ligne réside (le premier fichier est 1). Fichier nombre est relatif à l'espace de table.
l'équivalent le plus proche de cela dans SQL Server est le rid
qui a trois composants File:Page:Slot
.
dans SQL Server 2008, il est possible d'utiliser la colonne virtuelle non documentée et non supportée %%physloc%%
pour voir ceci. Cela renvoie une valeur binary(8)
avec L'ID de Page dans les quatre premiers octets, puis 2 octets pour L'ID du fichier, suivi de 2 octets pour l'emplacement de fente sur la page.
la fonction scalaire sys.fn_PhysLocFormatter
ou le sys.fn_PhysLocCracker
TVF peut être utilisé pour convertir cela dans une forme plus lisible
CREATE TABLE T(X INT);
INSERT INTO T VALUES(1),(2)
SELECT %%physloc%% AS [%%physloc%%],
sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot]
FROM T
Exemple De Sortie
+--------------------+----------------+
| %%physloc%% | File:Page:Slot |
+--------------------+----------------+
| 0x2926020001000000 | (1:140841:0) |
| 0x2926020001000100 | (1:140841:1) |
+--------------------+----------------+
Notez que c'est pas exploité par le processeur de requête. Alors qu'il est possible à utiliser dans une WHERE
clause
SELECT *
FROM T
WHERE %%physloc%% = 0x2926020001000100
SQL Server va pas chercher directement à la ligne spécifiée. Au lieu de cela, il effectuera un balayage complet de la table, évaluera %%physloc%%
pour chaque ligne et retournera celle qui correspond (s'il y a lieu).
pour inverser le processus effectué par les 2 fonctions précédemment mentionnées et obtenir le binary(8)
valeur correspondant à des valeurs connues de fichier,Page,Slot ci-dessous peut être utilisé.
DECLARE @FileId int = 1,
@PageId int = 338,
@Slot int = 3
SELECT CAST(REVERSE(CAST(@PageId AS BINARY(4))) AS BINARY(4)) +
CAST(REVERSE(CAST(@FileId AS BINARY(2))) AS BINARY(2)) +
CAST(REVERSE(CAST(@Slot AS BINARY(2))) AS BINARY(2))
si vous voulez identifier de façon unique une ligne dans la table plutôt que votre ensemble de résultats, alors vous devez regarder en utilisant quelque chose comme une colonne D'identité. Voir "propriété D'identité" dans L'aide de SQL Server. SQL Server ne génère pas automatiquement un ID pour chaque ligne de la table comme le fait Oracle, donc vous devez vous donner la peine de créer votre propre colonne ID et explicitement le récupérer dans votre requête.
EDIT: pour la dynamique de la numérotation des lignes de jeu de résultats voir ci-dessous, mais ce serait probablement un équivalent pour le ROWNUM D'Oracle et je suppose de tous les commentaires sur la page que vous voulez la substance ci-dessus. Pour SQL Server 2005 et les suivantes, vous pouvez utiliser la nouvelle fonction de classement pour obtenir une numérotation dynamique des lignes.
par exemple je le fais sur une requête de la mienne:
select row_number() over (order by rn_execution_date asc) as 'Row Number', rn_execution_date as 'Execution Date', count(*) as 'Count'
from td.run
where rn_execution_date >= '2009-05-19'
group by rn_execution_date
order by rn_execution_date asc
vous donnera:
Row Number Execution Date Count
---------- ----------------- -----
1 2009-05-19 00:00:00.000 280
2 2009-05-20 00:00:00.000 269
3 2009-05-21 00:00:00.000 279
il y a aussi un article sur support.microsoft.com sur les lignes à numérotation dynamique.
Vérifiez la nouvelle fonction ROW_NUMBER . Cela fonctionne comme ceci:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
plusieurs des réponses ci-dessus seront travailler autour de l'absence d'une référence directe à une ligne spécifique, mais ne fonctionnera pas si des changements se produisent aux autres lignes d'un tableau. C'est mon critère pour lequel les réponses sont techniquement insuffisantes.
une utilisation courante de ROWID D'Oracle est de fournir une méthode (quelque peu) stable de sélectionner des lignes et de revenir plus tard à la ligne pour la traiter (par exemple, pour la mettre à jour). La méthode pour trouver un ligne (des jointures complexes, la recherche plein texte, de la navigation ou ligne par ligne et en appliquant la procédure des tests sur les données) ne peut pas être facilement et en toute sécurité ré-utilisé pour qualifier l'instruction de mise à JOUR.
le SQL Server RID semble fournir la même fonctionnalité, mais ne fournit pas la même performance. C'est la seule question que je vois, et malheureusement l'objectif de conserver un ROWID est d'éviter de répéter une opération coûteuse pour trouver la rangée dans, disons, une très grande table. Néanmoins, dans de nombreux cas, le rendement est acceptable. Si Microsoft ajuste l'optimiseur dans une version future, le problème pourrait être résolu.
il est également possible d'utiliser simplement pour mettre à jour et garder le curseur ouvert dans un programme de procédure. Toutefois, cela pourrait s'avérer coûteux dans le cas d'un traitement par lots de grande envergure ou complexe.
mise en garde: même le ROWID D'Oracle ne serait pas stable si le DBA, entre le SELECT et la mise à jour, pour exemple, étaient de reconstruire la base de données, parce qu'il s'agit de l'Identificateur de ligne physique. Le dispositif ROWID ne doit donc être utilisé que dans le cadre d'une tâche bien précise.
je dois démonter une très grande table avec beaucoup de colonnes et la vitesse est importante. Ainsi j'utilise cette méthode qui fonctionne pour n'importe quelle table:
delete T from
(select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T
Where T.RowNumber > 1
de http://vyaskn.tripod.com/programming_faq.htm#q17 :
Oracle a un rownum pour accéder aux lignes d'une table en utilisant le numéro de ligne ou le numéro d'identification de ligne. Y a-t-il un équivalent pour cela dans SQL Server? Ou comment générer sortie avec le numéro de ligne dans le serveur SQL?
il n'y a pas d'équivalent direct au rownum ou au row id D'Oracle en SQL Serveur. À proprement parler, dans une base de données relationnelle, les lignes à l'intérieur d'un les tables ne sont pas ordonnées et un numéro d'identification de ligne n'a pas vraiment de sens. Mais si vous besoin de cette fonctionnalité, envisager les trois alternatives suivantes:
ajouter une colonne
IDENTITY
à votre tableau.Utiliser la requête suivante pour générer un numéro de ligne pour chaque ligne. La requête suivante génère un numéro de ligne pour chaque ligne dans les auteurs table de base de données pubs. Pour cette requête travailler, la table doit avoir un clé unique.
SELECT (SELECT COUNT(i.au_id) FROM pubs..authors i WHERE i.au_id >= o.au_id ) AS RowID, au_fname + ' ' + au_lname AS 'Author name' FROM pubs..authors o ORDER BY RowID
utilisez une approche de table temporaire, pour stocker l'ensemble des résultats dans une table temporaire, avec un ID de ligne généré par le
IDENTITY()
fonction. La création d'une table temporaire sera coûteuse, surtout si vous travaillez avec de grandes tables. Pour cette approche, si vous n'avez pas avoir une clé unique dans votre table.
si vous voulez numéroter en permanence les lignes dans le tableau, S'il vous plaît n'utilisez pas la solution RID pour SQL Server. Il sera pire que L'accès sur un vieux 386. Pour SQL Server, créez simplement une colonne D'identité, et utilisez cette colonne comme une clé primaire groupée. Cela placera un arbre B-entier permanent et rapide sur la table, et plus important encore, chaque index non-groupé l'utilisera pour localiser les lignes. Si vous essayez de vous développer dans SQL Server comme si C'était Oracle, vous créerez une mauvaise performance la base de données. Vous devez optimiser pour le moteur, pas prétendre que c'est un autre moteur.
aussi, s'il vous plaît n'utilisez pas le NewID() pour peupler la clé primaire avec des GUIDs, vous allez tuer la performance insert. Si vous devez utiliser GUIDs, utilisez NewSequentialID () comme colonne par défaut. Mais L'INT sera encore plus rapide.
si d'un autre côté, vous voulez simplement numéroter les lignes qui résultent d'une requête, utilisez la fonction RowNumber Over() comme l'une des colonnes de requête.
si vous voulez simplement numéroter une ligne de base pour un petit ensemble de données, que diriez-vous de quelque chose comme ça?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
ROWID est une colonne cachée sur les tables Oracle, donc, pour SQL Server, construisez la vôtre. Ajouter une colonne appelée ROWID avec une valeur par défaut de NEWID()
.
Comment faire: ajouter colonne, avec valeur par défaut, à la table existante dans le serveur SQL
le timestamp modifié garantit que vous mettez à jour les données originales et échouera si une autre mise à jour a eu lieu dans la rangée.
j'ai pris cet exemple de MS SQL exemple et vous pouvez voir le @ID peut être interchangé avec integer ou varchar ou quoi que ce soit. C'est la même solution que je cherchais, donc je le partage. Profitez-en!!
-- UPDATE statement with CTE references that are correctly matched.
DECLARE @x TABLE (ID int, Stad int, Value int, ison bit);
INSERT @x VALUES (1, 0, 10, 0), (2, 1, 20, 0), (6, 0, 40, 0), (4, 1, 50, 0), (5, 3, 60, 0), (9, 6, 20, 0), (7, 5, 10, 0), (8, 8, 220, 0);
DECLARE @Error int;
DECLARE @id int;
WITH cte AS (SELECT top 1 * FROM @x WHERE Stad=6)
UPDATE x -- cte is referenced by the alias.
SET ison=1, @id=x.ID
FROM cte AS x
SELECT *, @id as 'random' from @x
GO
vous pouvez obtenir le ROWID en utilisant les méthodes indiquées ci-dessous:
1.Créer une nouvelle table avec le champ auto increment EN it
2.Utilisez la fonction d'analyse Row_Number pour obtenir la séquence basée sur vos besoins.Je préférerais cela parce qu'il aide dans les situations où vous êtes vous voulez le row_id sur la manière ascendante ou descendante d'un champ spécifique ou d'une combinaison de champs
exemple: Row_Number () Over (Partition by Deptno ordonnance de sal desc)
ci-dessus vous donnera le numéro de séquence basé sur le salaire le plus élevé de chaque département.Partition by est facultatif et vous pouvez le supprimer selon vos exigences
essayez
select NEWID()
Source: https://docs.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql