https://coding-factory.tistory.com/

 

코딩팩토리

My life depends on my efforts

coding-factory.tistory.com

위 사이트 참조

 

ISNULL

- ISNULL은 반환 값이 NULL일 경우 설정된 값을 대신 반환하는 함수이다.

- ISNULL(칼럼, 칼럼이 NULL일 경우 대체할 값)

EX ) ISNULL(WSL.ORDERQTY, 0) - ISNULL(WSL.SHIPQTY, 0) AS NOTSHIPQTY

ISNULL을 사용하면 정의에서도 알 수 있드시 NULL값이 없어지게 된다.

 

IN

SELECT * FROM My_Table WHERE Age IN(20,24,26)

SELECT * FROM My_Table WHERE Age = 20 OR Age = 24 OR Age = 26

반대로 어떤 값에 해당사항이 없는 값을 불러오고 싶을 때는 NOT IN을 사용하면 된다.

 

참조하면 좋은 사이트

https://greatepig.tistory.com/19

 

[DB]프로시저 vs 사용자 정의 함수

<서론> 프로시저에 비즈니스 로직이 녹아있는 프로젝트를 하다보니 여러 프로시저 안에서 다른 프로시저를 부르는 경우를 많이 봤다. 그런데 간혹 프로시저 말고, 사용자 정의 함수를 호출하는

greatepig.tistory.com

PROCEDURE

프로지셔란 프로그래머가 생성해놓은 쿼리문을 마치 하나의 메서드 형식으로 관리된다.

 

기본적인 프로시져 형태 

CREATE PROCEDURE [프로시져명]
(
	@변수명 변수타입,
	@변수명 변수타입,
)
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

쿼리문

END;

변수명 앞에는 @을 사용해야 한다.

 

특징(사용자 정의 함수와 반대되는)

- 트랜잭션을 사용할 수 있다.

- SELECT, HAVING, WHERE 위에서 사용할 수 없다.

 

그 외 프로시져에서 자주 등장하는 구문

- SET NOCOUNT ON

  MSSQL에서 INSERT, UPDATE, 등을 사용하게 되면 영향받은 쿼리의 개수를 세어주는 기능이 있는데 이 기능은 딱히 의미 없는 기능이기 때문에 성능이 중요한 프로시져의 경우 SET NOCOUNT ON을 사용하여서 세어주는 기능을 사용하지 않을 수 있다.

 

- SET TRANSACTION ISOLATION LEVEL READ UNCOMMITEED

ISOLATION LEVEL은 격리 수준으로 현재 READ UNCOMMITED을 사용하고 있다.

격리 수준은 4가지가 있고 아래로 갈수록 격리 수준이 강해진다.

 

- READ UNCOMMITTED

- READ COMMITTED

- REPEATABLE READ

- SERIALIZABLE

 

여기서 READ UNCOMMITTED 같은 경우에는 트랜잭션이 실행은 되었지만 커밋되지 않은 데이터도 읽겠다는 뜻이다.

이렇게 될 경우 정합성의 문제가 발생하거나 더티 리드 현상이 발생하게 될 수도 있다.

 

 

 

 

 

 

 

           SELECT
             WMS.COMPANYID        /*회사코드*/
            ,WMS.DIVISIONID       /*사업장코드*/
            ,WMS.SOID             /*수주번호*/
            ,WMS.CUSTOMERID       /*거래처코드*/
            ,WMC.CUSTOMERNAME     /*거래처명*/
            ,WMS.ORDERDATE        /*수주일자*/
            ,WMS.DELIVERYDATE     /*납기일자*/
            ,WML.PRICE         /*수주금액*/
            ,WML.SOLINENO         /*행번*/
            ,WML.ITEMID           /*아이템코드*/
            ,WMI.ITEMNAME         /*아이템명*/
            ,WML.ORDERQTY         /*수주수량*/
            ,WML.SHIPQTY          /*출고수량*/
            ,(WML.ORDERQTY - WML.SHIPQTY) AS NOTSHIPQTY /*미출고수량*/
            ,WML.SHIPSTATE        /*출고상태*/
            ,WMS.REMARK           /*설명*/
            ,WMS.ISVALID
            FROM      
			WM_SALESORDER     WMS
            INNER JOIN WM_SALESORDERLINE WML        ON WMS.SOID       = WML.SOID        AND WML.ISVALID = 'Y'
            LEFT  JOIN WM_CUSTOMERINFO   WMC        ON WMS.CUSTOMERID = WMC.CUSTOMERID  AND WMS.COMPANYID = WMC.COMPANYID  AND WMS.DIVISIONID = WMC.DIVISIONID
            LEFT  JOIN WM_ITEMINFO       WMI        ON WML.ITEMID     = WMI.ITEMID
            WHERE
            WMS.COMPANYID = 1000
            AND WMS.DIVISIONID = 1000
			AND WMS.ORDERDATE BETWEEN '2021-01-01' AND '2021-01-30'
			AND WMS.SOID LIKE '%SO%'

위 쿼리문에서 주의 깊게 봐야될 조건은 BETWEEN 조건 AND 조건 과, LIKE '%' 이다.

BETWEEN은 어떤 값보다는 작고 어떤 값보다는 큰 조건을 만들 때 편리하게 사용할 수 있다.

어떤 단어를 검색할 때 특정 키워드만 사용하고 싶으면 %를 활용하면 된다. 

'-' : 글자숫자를 정해줌(EX 컬럼명 LIKE '홍_동')

'%' : 글자숫자를 정해주지않음(EX 컬럼명 LIKE '홍%')

SELECT * FROM WM_SALESORDER WHERE SOID = 'SO2011120002'

BEGIN TRAN
DELETE FROM WM_SALESORDER WHERE SOID = 'SO2011120002'
ROLLBACK TRAN

SELECT * FROM WM_SALESORDER WHERE SOID = 'SO2011120002'

위 쿼리문은 트랜잭션을 실험해보기 위함이다. 

BEGIN TRAN이 실행된 뒤 다음에 실행되는 쿼리문을 ROLLBACK TRAN을 이용하여 되돌린 후 다시 SELECT문을

사용하여 DELETE되기 전으로 되돌아 갔는지 확인하였고 결과는 ROLLBACK이 성공적으로 이루어 졌다.

 

INNER JOIN LEFT OR RIGHT OUTER JOIN

https://m.blog.naver.com/PostView.nhn?blogId=wideeyed&logNo=221435077767&proxyReferer=https:%2F%2Fwww.google.com%2F

 

[MSSQL] 조인(Inner Join, Outer Join)

조인(Join)이란 2개 이상 테이블을 서로 엮어 조회하는 것이다.​Inner Join은 서로 매칭되는 것만 엮어...

blog.naver.com

 

교집합(JOIN, INNER JOIN)
합집합

 

LEFT OUTER JOIN 과 LEFT JOIN은 같고 위에 WHERE 절이 빠지게 되면 교집합 부분도 포함하게 된다.

선언

Thread worker;

사용

스레드를 사용하기 전에 작업 스레드가 진행 중에 있으면 중단하고 제거하는 코드를 추가하였다. 

ParameterizedThreadStart()함수를 통해 매게변수를 필요로 하는 함수를 사용할 수 있고 매게변수가 없으면 스레드 생성 매개변수로 그냥 함수명을 주면 된다.

        private void button1_Click(object sender, EventArgs e)
        {
            int textbox_value = int.Parse(textBox1.Text);
            if (textbox_value <= 249 && textbox_value >= 1)
            {
                if (worker != null)
                {
                    if (worker.IsAlive)
                    {
                        //worker.Interrupt();
                        worker.Abort();
                    }
                }
                worker = new Thread(new ParameterizedThreadStart(Run));
                worker.Start(textbox_value);
            }

        }

스레드 함수

작업 스레드를 생성하여 얻을 수 있는 이점은 Thread.Sleep() 함수를 편안하게 사용할 수 있다.

만약 UI 스레드에서 Sleep을 사용하게 되면 모든 동작이 멈추게 될 것이다. 왜냐면 UI 스레드는 메인 스레드 주요한 대부분의 작업이 이루어지고 있는 스레드이기 때문이다. 

작업 스레드에서는 UI에 관련된 값에 직접 접근하면 문제가 발생한다. . UI 스레드와 작업 스레드에서 동시에 UI에 접근하는 상황은 예기치 못한 오류를 발생할 수 있기 때문에 BeginInvoke라는 함수를 사용하여 UI에 접근하도록 한다.  

        public void Run(object idx)
        {
            try
            {
                if (!this.IsHandleCreated)
                {
                    this.CreateHandle();
                }
                int frame_idx = Convert.ToInt32(idx);
                if (now_idx < frame_idx)
                {
                    // 전진
                    for (int i = now_idx; i <= frame_idx; i++)
                    {
                        string str = filename(i);
                        pictureBox1.BeginInvoke(new Action(() => pictureBox1.Load(str)));
                        now_idx = frame_idx;
                        Thread.Sleep(50);
                    }
                }
                else if (now_idx > frame_idx)
                {
                    // 후진
                    for (int i = now_idx; i >= frame_idx; i--)
                    {
                        string str = filename(i);
                        pictureBox1.BeginInvoke(new Action(() => pictureBox1.Load(str)));
                        now_idx = frame_idx;
                        Thread.Sleep(100);
                    }
                }
            }
            catch(Exception e)
            {

            }
        }

 

'C#' 카테고리의 다른 글

.NET Reflection  (0) 2021.03.29
Dbset 직접 바인딩 에러 해결법  (0) 2021.02.25
외부 프로젝트 참조하기  (0) 2021.02.25
[Winform] Dock  (0) 2021.01.22
C# Dictionary  (0) 2020.11.30

선언

타입이라는 것은 변수(Int,string, char)같은 것을 말한다.

Dictionary<key 타입,value 타입> IDTable;

 

생성

IDTable = new Dictionary<key 타입, value 타입>();

 

추가

딕셔너리는 중복 키를 허용하지 않는다. 따라서, 키 값을 추가하기전 딕셔너리에 값이 이미 있는지 확인하는 조건문을 Add 함수와 같이 사용한다. ContainsKey 함수는 찾길 원하는 키가 없어도 예외를 발생시키지 않는 특성있고 사용하길 추천한다.

if (!(IDTable.ContainsKey(찾길 원하는 키)))
	IDTable.Add(Key, Value);

 

접근

foreach문을 사용하여 키값을 기준으로 값을 찾거나 value값을 기준으로 값을 찾을 수 있다.

아래 foreach 조건문에는 딕셔너리.Keys를 사용하였고 이렇게 되면 for문에 key 문자열에는 key 값이 담기게 된다.

만약 딕셔너리.Values를 사용한다면 key 문자열에는 value값이 담기게 된다.

string fake_ip ="";
if (IDTable.ContainsKey(ip))
{
	string id = IDTable[ip];
		foreach (string Key in IDTable.Keys)
		{
			if (!(ip.Equals(Key)) && IDTable[Key].Equals(id))
			{
				fake_ip = Key;
				IDTable.Remove(fake_ip);
				IDTable.Remove(ip);
				break;
			}
		}
}

 

삭제

IDTable.Remove(key값);

 

 

'C#' 카테고리의 다른 글

.NET Reflection  (0) 2021.03.29
Dbset 직접 바인딩 에러 해결법  (0) 2021.02.25
외부 프로젝트 참조하기  (0) 2021.02.25
[Winform] Dock  (0) 2021.01.22
C# Thread  (0) 2020.12.01

사용법

1. 빈 오브젝트 추가후 Video Capture 2 Local Example 스크립트를 Component로 준다.

2. 위 이지에서 보이듯 Previewer라는 프리팹을 생성한 엠티 오브젝트의 자식으로 만든다.

 

3. 아래 보이는 text는 휴대폰 어느곳에 동영상이 저장되는지 확인하기 위함이다. 

 

아래 코드는 경로 확인을 위한 코드를 기존 코드에 추가한 내용이다.

using NRKernal.Record;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

namespace NRKernal.NRExamples
{
    [HelpURL("https://developer.nreal.ai/develop/unity/video-capture")]
    public class VideoCapture2LocalExample : MonoBehaviour
    {
        public NRPreviewer Previewer;

        [SerializeField]
        private Text text;

        // Save the video to Application.persistentDataPath
        public string VideoSavePath
        {
            get
            {
                string timeStamp = Time.time.ToString().Replace(".", "").Replace(":", "");
                string filename = string.Format("Nreal_Record_{0}.mp4", timeStamp);
                string filepath = Path.Combine(Application.persistentDataPath, filename);
                return filepath;
            }
        }

        NRVideoCapture m_VideoCapture = null;

        void Start()
        {
            CreateVideoCaptureTest();
        }

        void CreateVideoCaptureTest()
        {
            NRVideoCapture.CreateAsync(false, delegate (NRVideoCapture videoCapture)
            {
                if (videoCapture != null)
                {
                    m_VideoCapture = videoCapture;
                }
                else
                {
                    Debug.LogError("Failed to create VideoCapture Instance!");
                }
            });
        }

        public void StartVideoCapture()
        {
            Resolution cameraResolution = NRVideoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
            Debug.Log(cameraResolution);

            int cameraFramerate = NRVideoCapture.GetSupportedFrameRatesForResolution(cameraResolution).OrderByDescending((fps) => fps).First();
            Debug.Log(cameraFramerate);

            if (m_VideoCapture != null)
            {
                Debug.Log("Created VideoCapture Instance!");
                CameraParameters cameraParameters = new CameraParameters();
                cameraParameters.hologramOpacity = 0.0f;
                cameraParameters.frameRate = cameraFramerate;
                cameraParameters.cameraResolutionWidth = cameraResolution.width;
                cameraParameters.cameraResolutionHeight = cameraResolution.height;
                cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
                cameraParameters.blendMode = BlendMode.Blend;

                m_VideoCapture.StartVideoModeAsync(cameraParameters, OnStartedVideoCaptureMode);

                Previewer.SetData(m_VideoCapture.PreviewTexture, true);
            }
        }

        public void StopVideoCapture()
        {
            if (m_VideoCapture == null)
            {
                return;
            }
            Debug.Log("Stop Video Capture!");
            m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
            Previewer.SetData(m_VideoCapture.PreviewTexture, false);
        }

        void OnStartedVideoCaptureMode(NRVideoCapture.VideoCaptureResult result)
        {
            Debug.Log("Started Video Capture Mode!");
            // 경로 확인을 위해 추가한 코드
            text.text = VideoSavePath;
            m_VideoCapture.StartRecordingAsync(VideoSavePath, OnStartedRecordingVideo);
        }

        void OnStartedRecordingVideo(NRVideoCapture.VideoCaptureResult result)
        {
            Debug.Log("Started Recording Video!");
        }

        void OnStoppedRecordingVideo(NRVideoCapture.VideoCaptureResult result)
        {
            Debug.Log("Stopped Recording Video!");
            m_VideoCapture.StopVideoModeAsync(OnStoppedVideoCaptureMode);
        }

        void OnStoppedVideoCaptureMode(NRVideoCapture.VideoCaptureResult result)
        {
            Debug.Log("Stopped Video Capture Mode!");
        }
    }
}

tip)동영상 파일 경로를 찾는데 많은 시간을 사용하였기에 추가적으로 경로에 관한 이야기를 하겠다.

파일 경로는 Android 폴더에 data 폴더 안에 com.회사이름.product_name 폴더안에 파일에 동영상이 저장된다.

외부 프로그램을 실행시키기 위해 필요한 using

using System.Diagnostics;

프로세스를 윈도우 최상위 화면으로 활성화 시키기 위해 필요한 using

using System.Runtime.InteropServices;

    // 클래스 내부에 
    [DllImport("user32")]
    private static extern bool SetForegroundWindow(IntPtr handle);

       

 

외부 프로그램 실행 방법

// 실행파일 경로와 이름
string exe_name = Application.StartupPath + "\\process.exe";
// 실행파일 실행
Process.Start(exe_name);

Tip) 실행파일 이름에있는 확장자 .exe를 까먹으면 오류가 발생할 수 있다.

 

외부 프로그램 실행여부 확인 방법 & 화면에서 프로세스를 제일 위로 올리기

// Process.GetProcess(): 실행중인 프로세스 배열 반환
foreach(Process process in Process.GetProcesses())
{
	// "exe_name"라는 이름을 가진 프로세스가 존재하면 true를 리턴한다.
	if(process.ProcessName.StartsWith("exe_name"))
    {
    	// 프로세스를 윈도우 화면 최상단에 배치
    	SetForegroundWindow(process.MainWindowHandle);
    	// 프로세스를 죽이는 함수
    	process.Kill();
    }
}

 

삭제

dd - 현재 커서의 행 삭제

숫자 dd - 현재 커서부터 숫자만큼의 행삭제

x -현재 커서가 위치한 글자 삭제(Del)

X -현재 커서가 위치한 앞 글자 삭제

 

복사

yy - 현재 커서가 있는 행을 복사

숫자 yy - 현재 커서부터 숫자만큼의 행을 복사

p - 복사한 내용을 현재 행 이후에 붙여넣기

P - 복사한 내용을 현재 행 이전에 붙여넣기

 

문자열찾기

/문자열 - 해당 문자열을 찾음

n - 찾은 문자 중에서 다음 문자로 이동

 

행번호 표기하기

:set number or set nu

:set nonu

00-installer-config.yaml 파일을 설정시 주의해야 할점은 들여쓰기를 절대 틀려서는 안된다.

그리고 파일 설정일 끝났으면

$ sudo netplan try

명령어로 고정 IP 할당이 잘 되었는지 확인해보는 것이 좋다.

https://linuxhint.com/setup_static_ip_address_ubuntu/

 

Setting Up Static IP Address on Ubuntu 20.04 LTS – Linux Hint

Freelancer & Linux System Administrator. Also loves Web API development with Node.js and JavaScript. I was born in Bangladesh. I am currently studying Electronics and Communication Engineering at Khulna University of Engineering & Technology (KUET), one of

linuxhint.com

 

 

-------------------------------------------------------------------------------------------------

그외 리눅스 단축키

https://4475.tistory.com/489

 

리눅스 콘솔 단축키 및 명령어

리눅스 콘솔 단축키 Shift + PageUp : 상위 페이지 이동 Shift + PageDown : 아래 페이지 이동 출처 : http://andstory.com/zb41/zboard.php?id=tip_board&page=16&sn1=&divpage=1&sn=off&ss=on&sc=on&select_a..

4475.tistory.com

내가 필요한 단축키는 커멘드 창에 입력하던 명령어를 한번에 지울수 있는 단축키이다.

ctrl +u가 내가 찾던 명령어였는데 커서 뒤에있는 명령어를 바로 삭제해준다.

트리거에 자동차가 들어오면 레이저포인터로 가르키는 코드 해당 코드를 사용하는 게임 오브젝트는 LineRenderer 컴포넌트와 콜라이더 설정이 되어있어야 한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class lineRendererTest : MonoBehaviour
{
    private LineRenderer lineRenderer;

    // Start is called before the first frame update
    void Start()
    {
        lineRenderer = GetComponent<LineRenderer>();
        // 라인이 가지개될 색상 표현
        Material material = new Material(Shader.Find("Standard"));
        material.color = new Color(0, 195, 255, 0.5f);
        lineRenderer.startWidth = 0.2f;
        lineRenderer.endWidth = 0.2f;
        // 끝점과 시작점 2개
        lineRenderer.positionCount = 2;
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "Car")
        {
            lineRenderer.SetPosition(0, transform.position);
            lineRenderer.SetPosition(1, other.transform.position);
        }

    }

    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "Car")
        {
            lineRenderer.SetPosition(1, transform.position);
        }
    }
}

 

레이저 메터리얼을 위 그림과 같은 설정으로 변경하여준다. 그렇지 않으면 레이저에 색상이 검정색이나 분홍색만 나오고 설정한 색상을 표현하지 않는다.

+ Recent posts