Esto es lo que terminé usando para crear un subdirectorio desde GetPathLocator()
no generará un nuevo valor path_locator
para mí - que sólo interpretará hierarchyids
existente.
DECLARE @parentdir table(path hierarchyid not null);
DECLARE @subdir_locator hierarchyid
-- Create Parent Directory, OUTPUT inserted parent path
INSERT INTO FileTable0 (name,is_directory,is_archive)
OUTPUT INSERTED.path_locator into @parentdir
SELECT 'Directory', 1, 0
-- Create new path_locator based upon parent
SELECT @subdir_locator = dbo.GetNewPathLocator(path) from @parentdir
-- Create Subdirectory
INSERT INTO FileTable0 (name,path_locator,is_directory,is_archive)
VALUES ('subdirectory', @subdir_locator, 1, 0);
El bloque de código anterior utiliza la default path_locator value discovered here que construye una nueva representación hierarchyid
de un GUID (utilizando newid()
método, y el análisis sencillo). La función GetNewPathLocator()
no existe en ningún lugar de SQL Server que pude encontrar (hierarchyid.GetDescendant()
es lo más parecido que pude encontrar, pero no utilizó la estructura nativa en la que FileTable se basa). Tal vez en SQL.NEXT ...
CREATE FUNCTION dbo.GetNewPathLocator (@parent hierarchyid = null) RETURNS varchar(max) AS
BEGIN
DECLARE @result varchar(max), @newid uniqueidentifier -- declare new path locator, newid placeholder
SELECT @newid = new_id FROM dbo.getNewID; -- retrieve new GUID
SELECT @result = ISNULL(@parent.ToString(), '/') + -- append parent if present, otherwise assume root
convert(varchar(20), convert(bigint, substring(convert(binary(16), @newid), 1, 6))) + '.' +
convert(varchar(20), convert(bigint, substring(convert(binary(16), @newid), 7, 6))) + '.' +
convert(varchar(20), convert(bigint, substring(convert(binary(16), @newid), 13, 4))) + '/'
RETURN @result -- return new path locator
END
GO
La función GetNewPathLocator()
requiere también una vista de SQL getNewID
para solicitar una newid()
utilizando el trick from this SO post.
create view dbo.getNewID as select newid() as new_id
Para llamar GetNewPathLocator()
, puede utilizar el parámetro por defecto que generará un nuevo hierarchyid
o pasar de una representación hiearchyid
cadena existente (.ToString()
) para crear un niño hierarchyid
como se ve a continuación ...
SELECT dbo.GetNewPathLocator(DEFAULT); -- returns /260114589149012.132219338860058.565765146/
SELECT dbo.GetNewPathLocator('/260114589149012.132219338860058.565765146/'); -- returns /260114589149012.132219338860058.565765146/141008901849245.92649220230059.752793580/
Después de algunas pruebas rigurosas, parece que la instrucción de actualización es propenso a interbloqueos cuando este se llama en paralelo. – Tod