2023年9月22日 星期五

SQLServer 在資料庫中反向查詢字串值在哪個表裡

SQLServer 在資料庫中反向查詢字串值在哪個表裡

算是反向查詢吧,不知道表在那裏只知道數值,又正好這個數值足夠特別不是到處都有的,可以反向特定出位於哪個表格裡。



直接上代碼


-- 宣告搜尋的字串和結果表格
DECLARE @TargetString nvarchar(255) = '<要檢索的字串>';
DECLARE @SearchResults TABLE (
    TableType nvarchar(10),
    FullTableName nvarchar(500),
    ColumnName nvarchar(370),
    ColumnValue nvarchar(3630)
);

-- 宣告用於循環處理的變數
DECLARE 
    @CurrentTable nvarchar(256),
    @CurrentColumn nvarchar(128),
    @QueryString nvarchar(110),
    @CurrentTableType nvarchar(10),
    @DatabaseName nvarchar(128)

-- 初始設定
SET @CurrentTable = ''
SET @QueryString = QUOTENAME('%' + @TargetString + '%','''')
SET @DatabaseName = QUOTENAME(DB_NAME())

-- 在資料庫中迭代所有的表格和視圖
WHILE @CurrentTable IS NOT NULL
BEGIN
    SET @CurrentColumn = ''

    -- 獲取下一個表格或視圖名稱
    SET @CurrentTable =
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM INFORMATION_SCHEMA.TABLES
        WHERE (TABLE_TYPE = 'BASE TABLE' OR TABLE_TYPE = 'VIEW')
            AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @CurrentTable
            AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
    )

    -- 確定當前的表格/視圖類型
    SELECT @CurrentTableType = TABLE_TYPE
    FROM INFORMATION_SCHEMA.TABLES
    WHERE QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) = @CurrentTable

    -- 打印當前搜尋的表格或視圖名稱
    PRINT 'Searching ' + @DatabaseName + '.' + @CurrentTable + ' (Type: ' + @CurrentTableType + ')';

    -- 迭代當前表格/視圖的所有列
    WHILE (@CurrentTable IS NOT NULL) AND (@CurrentColumn IS NOT NULL)
    BEGIN
        -- 獲取下一個列名稱
        SET @CurrentColumn =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = PARSENAME(@CurrentTable, 2)
                AND TABLE_NAME  = PARSENAME(@CurrentTable, 1)
                AND QUOTENAME(COLUMN_NAME) > @CurrentColumn
        )

        -- 如果該列存在,則搜尋目標字串
        IF @CurrentColumn IS NOT NULL
        BEGIN
            BEGIN TRY
                SET NOCOUNT ON;
                INSERT INTO @SearchResults
                EXEC
                (
                    'SELECT ''' + @CurrentTableType + ''', ' + 
                        '''' + @DatabaseName + '.' + @CurrentTable + ''', ' + 
                        '''' + @CurrentColumn + ''', ' + 
                        'LEFT(CONVERT(nvarchar(3630), ' + @CurrentColumn + '), 3630) ' + 
                    'FROM ' + @CurrentTable + ' (NOLOCK) ' + 
                    'WHERE ' + @CurrentColumn + ' IS NOT NULL' + 
                        ' AND CONVERT(nvarchar(3630), ' + @CurrentColumn + ') LIKE ' + @QueryString
                )
                SET NOCOUNT OFF;
            END TRY
            BEGIN CATCH
                PRINT '  Warning: Skipped searching ' + @DatabaseName + '.' + @CurrentTable + ' (Type: ' + @CurrentTableType + ') perhaps due to potential locking issues.';
                PRINT '    Message: ' + ERROR_MESSAGE();
                BREAK;
            END CATCH
        END
    END 
END

-- 返回搜尋結果
SELECT TableType, FullTableName, ColumnName, ColumnValue FROM @SearchResults



2023年9月18日 星期一

刪除右鍵 "在Visual Studio中打開" 的選單

刪除右鍵 “在Visual Studio中打開” 的選單

對於希望右鍵選單簡潔強迫症的人來說,多這些用不到的選單真的很煩



停用右鍵選單

直接上命令快速停用

reg add "HKEY_CLASSES_ROOT\Directory\Background\shell\AnyCode" /v "LegacyDisable" /t REG_SZ /f
reg add "HKEY_CLASSES_ROOT\Directory\shell\AnyCode" /v "LegacyDisable" /t REG_SZ /f

執行完畢再回到桌面點右鍵該選單就會消失了



復原變更

由於沒有直接刪除原本的值,要復原的話刪除 LegacyDisable 這個項目即可

reg delete "HKEY_CLASSES_ROOT\Directory\Background\shell\AnyCode" /v "LegacyDisable" /f
reg delete "HKEY_CLASSES_ROOT\Directory\shell\AnyCode" /v "LegacyDisable" /f

就此就能輕易復原了



2023年9月13日 星期三

[Win10/Win11] 移除右鍵菜單中 "使用skype共享" 選項

[Win10/Win11] 移除右鍵菜單中 “使用skype共享” 選項



右鍵的選項不知道己版開始偷偷加了這東西,看了很礙眼這邊提供幾個方法消除。


從命令列輸入這行可以快速消除

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PackagedCom\Package\Microsoft.SkypeApp_15.103.3208.0_x64__kzf8qxf38zg5c\Class\{776DBC8D-7347-478C-8D71-791E12EF49D8}" /v "DllPath" /t REG_SZ /d "-Skype\SkypeContext.dll" /f


復原的話把 -Skype\SkypeContext.dll 中的負號移除即可,這邊僅添加負號盡可能保持原本的數據沒刪除了,可以很容易復原。




登陸檔位置在這裡

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PackagedCom\Package\Microsoft.SkypeApp_15.103.3208.0_x64__kzf8qxf38zg5c\Class\{776DBC8D-7347-478C-8D71-791E12EF49D8}







2023年9月10日 星期日

PowerShell 爬蟲自動化安裝 Maven 最新版本

PowerShell 爬蟲自動化安裝 Maven 最新版本

為了方便安裝,寫一個自動爬 Maven 官方最新版的爬蟲,再搭配自動化執行後續安裝的批次檔,可以實現全自動安裝。

主要是寫一個基礎版本,往後有什麼要自動化的參考這個版本就能快速修改了。
https://gist.github.com/hunandy14/0f3377e468ac85a589818295e3c3c27e


快速使用

irm bit.ly/3RdEkBK|iex; Install-Maven "C:\app"




在 Vscode 中使用 Java Maven 範例

在 Vscode 中使用 Java Maven 範例

Maven 可以用來建構和管理專案,包含對於庫的管理可以自動從支援的清單內自動下載,算是非常方便的省去不少建構上的麻煩。

這邊為了快速測試搭配 Vscode 做範例說明。




安裝 Maven

官方下載頁面:https://maven.apache.org/download.cgi
下載第二行的 Binary zip archive 這是我們要的檔案


載完之後找個合適的地方解壓縮,這邊用 C:\app 當範例,當前版本是 3.9.4 解出來後需要加到環境變數的位置會在

C:\app\apache-maven-3.9.4\bin


這邊用 PowerShell 加入環境變數 (需要使用管理員模式開啟)

[Environment]::SetEnvironmentVariable("PATH", "$($env:Path);C:\app\apache-maven-3.9.4\bin;", "Machine")


加完之後就能用了,用這個指令測試能不能用

mvn -v

如上圖那樣就是正確安裝好了


如果出現找不到 JAVA_HOME 的話表示電腦沒安裝 JAVA,這邊懶人包補裝一下就好
https://www.oracle.com/java/technologies/downloads/#jdk20-windows





從 vscode 執行 java 範例程式

先從套件區下載 Maven for Java 安裝



然後建立一個空資料 Demo 用 vscode 開啟


vscode 中按下 Ctrl+Shift+P 叫出命令列安裝
輸入 Maven後選擇 建立 Maven 專案



選擇快速建立



選擇1.4



網址預設狀態直接 Enter 即可



專案名稱預設 Demo 即可



選擇建立的位置,因為剛剛已經先建立好了直接Enter就好



選取資料夾之後注意看底下有對話要回復,版本輸入1.0按 Enter



然後會讓你確認是否正確,輸入Y之後就會自動建立好範例專案了



再來就建立好了



按下F5可以看到程式跑的結果



到此範例程式就生成完畢並成功執行了




添加 Lib 庫

套件查詢網頁: https://mvnrepository.com/


Maven的Lib庫管理是寫在 pom.xml 這個裡面裡面的,打開之後可以看到預設他有一個 junit 要追加的話,就在這個區塊前後添加即可



這邊舉個例子添加 sqlserver 的套件,需要的代碼可以從網站中查到,其中我選擇 12.4.0.jre8



版本點進來就有 Maven 用的代碼了



貼到剛剛 juint 附近,存檔之後右下角選是 Yes,按了會自動檢查有沒有貼錯




正確無誤之後再來在底下終端機輸 cd demo 進入 pom.xml 所在位置,然後再輸入 mvn clean install 清除已經編譯的檔案然後再重新編譯(會順便下載缺失的lib套件)



就此就完成了下載lib庫了,可以直接在代碼使用該庫的函式了




2023年9月3日 星期日

SQL Server 如何加密連接 Server/Client 端解說

[SQL Server] sqlcmd命令 如何加密連接 Server/Client 端解說

加密連接可以只單獨改一邊即可,當然伺服器端能直接強制加密是最好,就不用每一台客戶端都還要去更動。



測試是否正在加密中

在開始之前先說明這個指令可以用來測試是否加密中,請把它保存到 encrypt.sql 之中待會會用到。

SET NOCOUNT ON
SELECT
    c.session_id,
    c.encrypt_option,
    s.login_name,
    c.client_net_address,
    s.program_name
FROM
    sys.dm_exec_connections c
JOIN
    sys.dm_exec_sessions s ON c.session_id = s.session_id

保存好之後可以打開 SSMS 或 AzureDataStudio 測試一下這個 Querry 的結果。而這兩個軟體可以直接在圖形介面中選擇加密與信任伺服器就可以加密了。

下圖以 AzureDataStudio 為例子選中這兩個就能實現加密了



然後這是執行結果



其中的 SQLServerCEIP 這個東西是表示此連接與客戶體驗改進計劃 (CEIP) 有關,該計劃會定期從安裝的SQL Server中收集基本信息以幫助Microsoft改進其產品。

可以看到傳輸的信息已經是加密狀態了,這個可以一次看到全部所有的人加密狀態。如過要限縮範圍到當次連線的會話可以在 sql 中追加下面這段。

WHERE
    c.session_id = @@SPID



伺服器端的設定

打開 SQL Server 設定管理員從這裡強制打開



打開之後再從這裡重新啟動一下服務才會生效



再來絕大多數客戶端就算沒有特別改什麼也會生效被強制加密的



客戶 sqlcmd 端設定

如果伺服器端無法強制啟用只能從客戶端下手,這邊需要在命令加上 -N -C 這樣可以由客戶端強制加密連線

sqlcmd -S '192.168.3.123,1433' -U 'sa' -P '12345678' -i '.\encrypt.sql' -W -N -C

執行結果



可以看到已經是加密狀態了




快速測試

如果不希望外置SQL檔案想直接整合寫在命令列,以便快速測試可以用這條命令
sqlcmd -S '192.168.3.123,1433' -U 'sa' -P '12345678' -Q 'SET NOCOUNT ON SELECT c.session_id, c.encrypt_option, s.login_name, c.client_net_address, s.program_name FROM sys.dm_exec_connections c JOIN sys.dm_exec_sessions s ON c.session_id = s.session_id WHERE c.session_id = @@SPID' -W -N -C


對於該命令

  • 測試伺服啟有沒有啟用加密,要消除結尾的 -N -C 解除強制加密
  • 顯示包含其他連線,要消除 WHERE c.session_id = @@SPID


加密的選項

  • -N:由客戶端強制加密
  • -C:無條件信任證書

信任證書主要是用在如果證書不是買來的而是自己生成的,那麼預設情況下會被檔下來,以避免你連到別人假冒的服務器上

作為企業內部的網站並不公開可能不是那麼有必要買證書,不想花錢的話可以把自簽署證書加入信任清單,這樣即使不使用 -C 也可以正常連接




2023年8月22日 星期二

PowerShell 讀取檔案各種寫法利弊

PowerShell 讀取檔案各種寫法利弊

讀檔的方式其實蠻多的這邊大致介紹一下區別與效能影響



Get-Content

這是最常見的最快速的方法讀取出來是一個陣列物件,依照每行分配。

在絕大多數情況下是最方便快速的。

使用範例

Get-Content $Path

唯一的問題大概就是 Encoding 有限,只能用萬國碼或當前電腦編碼。還有性能沒有使用C#函式來得好。



[System.IO.File]::ReadAllLines()

遇到Encoding問題的時候首選的方案是這個,可以自由的設定編碼,而且有著較好的效能。

編碼問題大概比較容易遇到的狀況是

  1. 在舊版的 5.1 需要輸出不帶BOM的UTF8
  2. 非電腦編碼的其他語言

這兩種狀況都不是 Get-Content 能解決得,只能使用C#的函式

使用範例

$Enc = [Text.Encoding]::GetEncoding('UTF-8')
[System.IO.File]::ReadAllLines($Path, $Enc)

如果希望讀進來的不是陣列,使用 ReadAllText() 讀進來會是有換行的字串

要說缺點大概就是這東西不支持流,不支持流有個大問題是對於記憶體消耗比較重,假設今天要搬一個100G大小的文件,記憶體就得有100G才行,如果支持流可以讀一行寫一行自然對記憶體的負擔比較小了。



System.IO.StreamReader

這個大概是最好使的利器了,性能跟 ReadAllLines 一樣,而且支持流讀取與自訂 Encoding。檔案的指標移動也有支持,跟其他語言的讀取檔案差不多意思。

相比於前面這個函式是唯一可以解決缺少結尾空行的辦法了,前兩個其實都有個問題是會吃到一行結尾空行,因為for迴圈是在內部運行的,無權干預,這個可以自己寫能有效避開缺行的問題。

使用範例

$StreamReader = New-Object System.IO.StreamReader($Path, $Enc)
while ($null -ne ($line = $StreamReader.ReadLine())) {
    $line
}
if ($null -ne $StreamReader) { $StreamReader.Dispose() }

缺點也是一目了然,前後要開檔關檔還要寫 While 迴圈,對於快速測試來說這東西絕對不是首選。



Encoding編碼表查詢

最後附上各種常見編碼的查詢方法

# 日文::Shift-JIS (932)
[Text.Encoding]::GetEncoding('Shift-JIS')
# 簡體中文::GB2312 (936)
[Text.Encoding]::GetEncoding('GB2312')
# 繁體中文::BIG5 (950)
[Text.Encoding]::GetEncoding('BIG5')
# 萬國碼::UTF8 (65001)
[Text.Encoding]::GetEncoding('UTF-8')

# 萬國碼::UTF8-BOM (65001)
(New-Object System.Text.UTF8Encoding $True)
# 萬國碼::UTF8-NonBOM (65001)
(New-Object System.Text.UTF8Encoding $False)

# 當前系統編碼
PowerShell -Nop "& {return [Text.Encoding]::Default}"
# 當前 PowerShell 編碼
[Text.Encoding]::Default