开发者

SQL text wrapping

Hello and good afternoon. I am facing an issue with the system i support. I am able to build "Macros" which can pull sql views to a document. The issue is that the columns for these views do not wrap on the document. If a certain row contains too much text, it will push the other columns out of line. To resolve this i am trying to build a function to use with my view that will sort of brute force the wrap by looping through each row and creating an additional row to hold text for certain columns where the text limit was reached. I have something that works, but it's te开发者_如何学Crribly slow at times. Does anyone have any ideas on how i can optimize this?

(  

)  
RETURNS @medlist2 TABLE (uniq_id UNIQUEIDENTIFIER, enterprise_id CHAR(5), practice_id CHAR (4), person_id UNIQUEIDENTIFIER, 
enc_id UNIQUEIDENTIFIER, medication_name VARCHAR (70), sig_desc VARCHAR (512), start_date VARCHAR(10), row_num INT)

AS  
  BEGIN  

DECLARE @medlist TABLE (uniq_id UNIQUEIDENTIFIER, enterprise_id CHAR (5), practice_id CHAR (4), person_id UNIQUEIDENTIFIER, 
enc_id UNIQUEIDENTIFIER, medication_name VARCHAR (70), sig_desc VARCHAR (512), start_date DATETIME, processed INT)
DECLARE @medicationName VARCHAR (70)
DECLARE @sigDesc VARCHAR (512)
DECLARE @startDate VARCHAR (10)
DECLARE @uniqID UNIQUEIDENTIFIER
DECLARE @enterpriseID CHAR (5)
DECLARE @practiceID CHAR (4)
DECLARE @personID UNIQUEIDENTIFIER
DECLARE @encID UNIQUEIDENTIFIER
DECLARE @RowNum INT
DECLARE @RowCount INT

INSERT INTO @medlist (uniq_id, enterprise_id, practice_id, person_id, 
enc_id, medication_name, sig_desc, start_date, processed)
SELECT uniq_id, enterprise_id, practice_id, person_id, 
enc_id, medication_name, sig_desc, start_date, 0
FROM med_table
WHERE person_id IN (select distinct person_id from active_users where create_timestamp > GETDATE()-.2)
AND date_stopped = ''
ORDER BY medication_name

SET @RowCount = (SELECT COUNT(*) FROM @medlist WHERE processed = 0)
SET @RowNum = 0

WHILE @RowCount > 0
BEGIN

    SET @RowNum = @RowNum + 1

    SELECT TOP(1) @uniqid = uniq_id, @enterpriseID = enterprise_id, @practiceID = practice_id, 
    @personID = person_id, @encID = enc_id, @medicationName = '- ' +medication_name, @sigDesc = sig_desc, 
    @startDate = CONVERT(VARCHAR(10), start_date, 101)
    FROM @medlist
    WHERE processed = 0

    INSERT INTO @medlist2(uniq_id, enterprise_id, practice_id, person_id, 
    enc_id, start_date, row_num, medication_name, sig_desc)
    SELECT @uniqID, @enterpriseID, @practiceID, @personID, @encID, @startDate, @RowNum,
    (CASE WHEN DATALENGTH(@medicationName) > 28 THEN LEFT(@medicationNAME, 28) + '-' ELSE @medicationName END), 
    (CASE WHEN DATALENGTH(@sigDesc) > 41 THEN LEFT(@sigDesc, 41) + '-' ELSE @sigDesc END)

        WHILE DATALENGTH(@sigDesc) > 42 OR DATALENGTH(@medicationName) > 29
        BEGIN

        SET @medicationName = substring(@medicationName, 29,DATALENGTH(@medicationName))
        SET @sigDesc = substring(@sigDesc, 42,DATALENGTH(@sigDesc))
        SET @RowNum = @RowNum + 1

        INSERT INTO @medlist2 (uniq_id, enterprise_id, practice_id, person_id, 
        enc_id, medication_name, sig_desc, row_num)
        SELECT @uniqID, @enterpriseID, @practiceID, @personID, @encID, LEFT(@medicationNAME, 28), LEFT(@sigDesc, 41), @RowNum

        IF DATALENGTH(@sigDesc) < 42 OR DATALENGTH(@medicationName) > 29
            BREAK
        ELSE
            CONTINUE
        END

    UPDATE @medlist
    SET processed = 1
    WHERE uniq_id = @uniqID

    SET @RowCount = (SELECT COUNT(*) FROM @medlist WHERE processed = 0)

IF @RowCount = 0
    BREAK
ELSE
    CONTINUE
END 
    RETURN  
END


Don't do this in the database. Do it in your application layer!

Something as trivial as wrapping text is extremely expensive when SQL server is doing it on a row-by-row bases, but should be very quick to do in whatever application is displaying your results.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜